using iWareCommon; using iWareCommon.Utils; using iWareSql; using System; using System.Collections.Generic; using System.Threading; using iWareCC.SrmService; using System.Linq; using iWareSql.Orm; using System.Threading.Tasks; using iWareSql.Entity.ParamModel; using Newtonsoft.Json; using iWareCC.BLL; using iWareCC.Common; using iWareModel; using iWareCommon.Common.Globle; using XiGang.Core.Model; using iWareCC.Common.Helper; using iWareModel.EnumType.AoSinPublicCommon; using Admin.NET.Core.TaskModule.Enum; using iWareSql.DbOrm; using iWareSql.DataAccess; using static WZ.Useful.Commons.DGVPrinter; using System.Runtime.Remoting.Contexts; namespace iWareCC { /// /// 堆垛机任务服务线程类 /// public class SrmTaskThreadService : DeviceThreadServiceHandle { private static string _namespace = "iWareCC.SrmTaskThreadService"; private SrmTaskThreadService() { } public SrmTaskThreadService(iWareCommon.Utils.LogType logType) { base.currentLogType = logType; } public override void StartService() { Task.Run(() => { try { //自动执行堆垛机任务线程 Log4NetHelper.WriteInfoLog(base.currentLogType, "自动执行堆垛机任务线程启动了"); //var srmList = new SrmService.SrmServiceClient().GetSrm_CacheEntity(); var srmList = FormCC.SrmDeviceList; foreach (var x in srmList) { IssueTaskThread(x); ConfirmFinishTaskThread(x); } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(base.currentLogType, "SrmTaskThreadService线程启动出现异常", ex); } }); } #region 线程处理 #region 自动执行堆垛机任务线程 /// /// 自动执行堆垛机任务 /// /// public override void IssueTask(object deviceId) { string errMsg1 = "", errMsg2 = "", errMsg3 = "", errMsg4 = ""; int i_deviceId = (int)deviceId; while (true) { if ((int)deviceId == (int)EDevice.堆垛机 && SystemValue.isStartedModel) { IssueTaskHandle(i_deviceId, out errMsg1); } //else if ((int)deviceId == (int)EDevice.二号堆垛机 && SystemValue.isAllowRuning_SrmTaskThreadService_2 && SystemValue.isStartedModel) //{ // IssueTaskHandle(i_deviceId, out errMsg2); //} SystemWarningMsg._lbl_Alert_Srm1Release = errMsg1; SystemWarningMsg._lbl_Alert_Srm2Release = errMsg2; Thread.Sleep(500);//2秒一次 } } /// /// 自动执行堆垛机任务(线程) /// /// public override void IssueTaskHandle(int deviceId, out string errMsg) { errMsg = ""; try { int int_deviceId = (int)deviceId; var vs = new SrmServiceClient(); //2、判断堆垛机是否可以下发新任务 SdaResEntity sdaResult = vs.IsAllowSendTask(int_deviceId, out errMsg); if (sdaResult.result == false) { errMsg = $"非自动、有任务未确认或有报警,{errMsg}"; return; } //bool isOk = ValidateDeviceIsAllowSendTask(int_deviceId, out errMsg); //if (!isOk) //{ // errMsg = "不允许下发新任务," + errMsg; // return; //} using (DbOrm dbOrm = new DbOrm()) { var srmTaskList = ValidateIsExistTaskToDisposeForIssued(dbOrm, int_deviceId, out errMsg); if (srmTaskList == null || srmTaskList.Count == 0) { //表示DB中没有任务要发送给堆垛机 errMsg = $"没有要执行的堆垛机任务"; return; } foreach (var item in srmTaskList) { SingleIssueTaskHandle(item, dbOrm, int_deviceId, vs, out errMsg); if (!string.IsNullOrEmpty(errMsg)) {//说明报错了,继续走下一个循环 continue; } else {//说明执行成功了,跳出循环 //修改下发的堆垛机任务状态,0->1 item.TaskState = (int)SubTaskStateEnum.已下发; dbOrm.SaveChanges(); break; } } } vs.Close(); } catch (Exception ex) { errMsg = "异常,请联系管理员:" + ex.Message; //SysExceptionInfoHandler.GetExceptionInfoForError("自动执行堆垛机任务(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception); //SysExceptionInfoHandler.InsertExceptionInfo(exception, true); } } private string GetRealLocatiomCodeOut(string sourcePlace) { switch (sourcePlace) { case "102": return "1-00-901-00"; //case "202": // return "1-00-902-00"; //case "203": // return "2-00-901-00"; //case "204": // return "2-00-902-00"; default: return "ERROR"; } } private string GetRealLocatiomCodeIn(string sourcePlace) { switch (sourcePlace) { case "102": return "1-00-801-00"; //case "202": // return "1-00-802-00"; //case "203": // return "2-00-801-00"; //case "204": // return "2-00-802-00"; default: return "ERROR"; } } /// /// 单个堆垛机任务下发处理 /// /// /// /// /// /// private void SingleIssueTaskHandle(ware_task_sub srmTask, DbOrm dbOrm, int int_deviceId, SrmServiceClient vs, out string errMsg) { #region //3、判断数据库中是否有可要下发的任务,如果有就下发 DeviceTaskTypeEnum _DeviceTaskTypeEnum = (DeviceTaskTypeEnum)Enum.Parse(typeof(DeviceTaskTypeEnum), srmTask.TaskType.ToString()); EDevice device = (EDevice)Enum.Parse(typeof(EDevice), int_deviceId.ToString()); string realSourcePlace = ""; string realToPlace = ""; bool isOk; if (srmTask.TaskType == (int)TaskCategoryEnum.InStock) { realSourcePlace = GetRealLocatiomCodeIn(srmTask.SourcePlace); realToPlace = srmTask.ToPlace; if (realToPlace.Substring(2).StartsWith("02")) { //查看该1排是否有货 var arr = realToPlace.Split('-'); string newstr = arr[0] + "-" + "01" + "-" + arr[2] + "-" + arr[3]; //看1排是否有货,无货放1排 var lvc = dbOrm.ware_location_vs_container.AsNoTracking().Any(u => u.WareLocationCode == newstr); if (!lvc) { var container1 = dbOrm.wms_container.Where(u => u.RealLocationCode == newstr).FirstOrDefault(); if (container1 != null) { container1.RealLocationCode = realToPlace; } //查看是否有指向1排原绑定库位的任务 var newtask = dbOrm.ware_task.Where(u => u.ToLocationCode == newstr).FirstOrDefault(); if (newtask != null) { newtask.ToLocationCode = realToPlace; var newtasksub = dbOrm.ware_task_sub.Where(u => u.TaskId == newtask.Id && u.DeviceId == int_deviceId && u.ToPlace == newstr).FirstOrDefault(); if (newtasksub != null) { newtasksub.ToPlace = realToPlace; } } //目标库位修改为1排 realToPlace = newstr; var container = dbOrm.wms_container.Where(u => u.ContainerCode == srmTask.ContainerCode).FirstOrDefault(); container.RealLocationCode = newstr; srmTask.ToPlace = realToPlace; //主任务也修改 var maintask = dbOrm.ware_task.Where(u => u.Id == srmTask.TaskId).FirstOrDefault(); maintask.ToLocationCode = realToPlace; } } //else if (realToPlace.Substring(2).StartsWith("01")) //{ // //查看该1排是否有货 // var arr = realToPlace.Split('-'); // string newstr = arr[0] + "-" + "02" + "-" + arr[2] + "-" + arr[3]; // var lvc = dbOrm.ware_location_vs_container.AsNoTracking().Any(u => u.WareLocationCode == realToPlace); // if (lvc)//有货就换到2排 // { // //目标库位修改为1排 // realToPlace = newstr; // var container = dbOrm.wms_container.Where(u => u.ContainerCode == srmTask.ContainerCode).FirstOrDefault(); // container.RealLocationCode = realToPlace; // srmTask.ToPlace = realToPlace; // //主任务也修改 // var maintask = dbOrm.ware_task.Where(u => u.Id == srmTask.TaskId).FirstOrDefault(); // maintask.ToLocationCode = realToPlace; // } //} isOk = dbOrm.ware_location_vs_container.Any(x => x.WareLocationCode == realToPlace && x.WareContainerCode != srmTask.ContainerCode && x.IsDeleted == false); if (isOk) { errMsg = device.ToString() + "不允许下发新任务,目标库位" + realToPlace + "系统显示有库存"; return; } } else if (srmTask.TaskType == (int)TaskCategoryEnum.OutStock) { realSourcePlace = srmTask.SourcePlace; realToPlace = GetRealLocatiomCodeOut(srmTask.ToPlace); //判断是否存在指向放货站台的执行中的任务 isOk = dbOrm.ware_task_sub.Any(x => x.ToPlace == srmTask.ToPlace && x.TaskState == (int)SubTaskStateEnum.已下发); if (isOk) { errMsg = "存在指向目标点" + srmTask.ToPlace + "的任务,不能下发同一目标点的任务"; return; } } else { realSourcePlace = srmTask.SourcePlace; realToPlace = srmTask.ToPlace; if (realToPlace.Substring(2).StartsWith("02") && realToPlace != "1-02-06-04") { //查看该1排是否有货 var arr = realToPlace.Split('-'); string newstr = arr[0] + "-" + "01" + "-" + arr[2] + "-" + arr[3]; //看1排是否有货,无货放1排 var lvc = dbOrm.ware_location_vs_container.AsNoTracking().Any(u => u.WareLocationCode == newstr); if (!lvc) { var container1 = dbOrm.wms_container.Where(u => u.RealLocationCode == newstr).FirstOrDefault(); if (container1 != null) { container1.RealLocationCode = realToPlace; } //查看是否有指向1排原绑定库位的任务 var newtask = dbOrm.ware_task.Where(u => u.ToLocationCode == newstr).FirstOrDefault(); if (newtask != null) { newtask.ToLocationCode = realToPlace; var newtasksub = dbOrm.ware_task_sub.Where(u => u.TaskId == newtask.Id && u.DeviceId == int_deviceId && u.ToPlace == newstr).FirstOrDefault(); if (newtasksub != null) { newtasksub.ToPlace = realToPlace; } } //目标库位修改为1排 realToPlace = newstr; var container = dbOrm.wms_container.Where(u => u.ContainerCode == srmTask.ContainerCode).FirstOrDefault(); container.RealLocationCode = newstr; srmTask.ToPlace = realToPlace; //主任务也修改 var maintask = dbOrm.ware_task.Where(u => u.Id == srmTask.TaskId).FirstOrDefault(); maintask.ToLocationCode = realToPlace; } } //判断是否存在指向放货站台的执行中的任务 isOk = dbOrm.ware_task_sub.Any(x => x.ToPlace == srmTask.ToPlace && x.TaskState == (int)SubTaskStateEnum.已下发); if (isOk) { errMsg = "存在指向目标点" + srmTask.SourcePlace + "的任务,不能下发同一目标点的任务"; return; } } //判断堆垛机是否有执行中的任务任务 【EditBy kejj,2022-09-22】 isOk = dbOrm.ware_task_sub.Any(u => u.DeviceId == int_deviceId && u.TaskState == (int)SubTaskStateEnum.执行中); if (isOk) { errMsg = "不允许下发新任务,当前堆垛机存在执行中的任务"; return; } //同一个关联任务的其他设备任务 var relevanceTask = dbOrm.ware_task_sub.Where(x => x.TaskId == srmTask.TaskId && x.TaskSequence < srmTask.TaskSequence && x.TaskState == (int)SubTaskStateEnum.未开始).FirstOrDefault(); if (relevanceTask != null) { errMsg = string.Format("关联{0}任务未开始,所以堆垛机任务不允许下发!关联任务号:{1}", Enum.Parse(typeof(EDevice), relevanceTask.DeviceId.ToString()).ToString(), relevanceTask.TaskNo); return; } ESrmCmd eSrmCmd; if (srmTask.TaskType == (int)TaskCategoryEnum.InStock) { eSrmCmd = ESrmCmd.入库; } else if (srmTask.TaskType == (int)TaskCategoryEnum.OutStock) { eSrmCmd = ESrmCmd.出库; } else { eSrmCmd = ESrmCmd.库内搬运; } SdaResEntity sdaResult = new SdaResEntity(); try { if (WCSConfigHelper.GetConfig_IsSimulationPLC()) { sdaResult.result = true; } else { if (Convert.ToInt32(srmTask.TaskNo) <= 0) { throw new Exception("任务号不能小于等于0,PlcTaskId:" + srmTask.TaskNo); } //short pallettype = GetSrmContainerType(srmTask.ContainerType); short pallettype = Convert.ToInt16(srmTask.ContainerType); if (pallettype == 0) { throw new Exception("托盘类型不能等于0,PlcTaskId:" + srmTask.TaskNo); } sdaResult = vs.SendSrmTask(int_deviceId, Convert.ToInt32(srmTask.TaskNo), realSourcePlace, realToPlace, (short)eSrmCmd, /*GetSrmContainerType(*/Convert.ToInt16(srmTask.ContainerType)/*)*/); } if (sdaResult.result == false) {//给堆垛机下发指令失败 //exception.exceptionMsg = string.Format("发送指令给堆垛机失败,设备号{0},任务ID{1},起始位{2},目标位{3},ContainerId{4}", int_deviceId, // Convert.ToInt32(srmTask.TaskNo), realSourcePlace, realToPlace, srmTask.ContainerCode); //SysExceptionInfoHandler.InsertExceptionInfo(exception, true); errMsg = string.Format("发送指令给堆垛机失败,设备号{0},任务ID{1},起始位{2},目标位{3},ContainerId{4}", int_deviceId, Convert.ToInt32(srmTask.TaskNo), realSourcePlace, realToPlace, srmTask.ContainerCode); return; } else { //SystemValueUtil.DelayExcuteForSrmTaskThreadService(int_deviceId, ThreadDirectionEnum.任务开始下发线程); errMsg = ""; } } catch (Exception ex) { throw ex; } #endregion } public short GetSrmContainerType(int? conveyorContainerType) { if (conveyorContainerType == 1) { return 2; } else if (conveyorContainerType == 3) { return 1; } else { return 0; } } #endregion #region 自动结束堆垛机任务线程 /// /// 自动结束堆垛机任务线程 /// /// public override void ConfirmFinishTask(object deviceId) { string errMsg1 = "", errMsg2 = "", errMsg3 = "", errMsg4 = ""; int i_deviceId = (int)deviceId; while (true) { if ((int)deviceId == (int)EDevice.堆垛机 && SystemValue.isStartedModel) { ConfirmFinishTaskHandle(i_deviceId, out errMsg1); } //else if ((int)deviceId == (int)EDevice.二号堆垛机 && SystemValue.isAllowRuning_SrmTaskThreadService_2_Finish && SystemValue.isStartedModel) //{ // ConfirmFinishTaskHandle(i_deviceId, out errMsg2); //} SystemWarningMsg._lbl_Alert_Srm1ReleaseFinish = errMsg1; SystemWarningMsg._lbl_Alert_Srm2ReleaseFinish = errMsg2; Thread.Sleep(500);//设置2秒一次 } } /// /// 自动结束堆垛机任务线程(线程) /// /// public override void ConfirmFinishTaskHandle(int deviceId, out string errMsg) { errMsg = ""; try { /* * 执行发送给堆垛机的指令任务 * 1、验证根据设备号是否找到堆垛机 * 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3 * 3、判断数据库中是否有可要完成的任务,如果有判断是否跟堆垛机中的完成任务相符,如果相符就处理 * 4、更新任务状态 */ int int_deviceId = (int)deviceId; var vs = new SrmService.SrmServiceClient(); using (DbOrm dbOrm = new DbOrm()) { #region //3、判断数据库中是否有可要完成的任务,如果有判断是否跟堆垛机中的完成任务相符,如果相符就处理 var currentTask = ValidateIsExistTaskToDispose(dbOrm, int_deviceId, out errMsg, SubTaskStateEnum.已完成); if (currentTask == null) {//表示DB中没有任务要发送给堆垛机 errMsg = "没有堆垛机任务数据要处理"; return; } #endregion //2、判断设备是否任务完成 //var isFinished = ValidateDeviceTaskIsFinsished(int_deviceId, currentTask, Convert.ToInt32(currentTask.TaskNo), (DeviceTaskTypeEnum)Enum.Parse(typeof(DeviceTaskTypeEnum), currentTask.TaskType.ToString()), true, out errMsg); //if (!isFinished) return; SdaResEntity sdaResult = vs.IsTaskFinish(int_deviceId, Convert.ToInt32(currentTask.TaskNo)); if (sdaResult.result != true) { errMsg = $"验证堆垛机是否任务完成 失败:{sdaResult.resMsg}"; return; } //同一个关联任务的其他设备任务 var relevanceTask = dbOrm.ware_task_sub.Where(x => x.TaskId == currentTask.TaskId && x.TaskSequence < currentTask.TaskSequence && (x.TaskState != (int)SubTaskStateEnum.已完成)).FirstOrDefault(); if (relevanceTask != null) { errMsg = string.Format("关联{0}任务未完成,所以堆垛机任务不允许完成!关联任务号:{1}", Enum.Parse(typeof(EDevice), relevanceTask.DeviceId.ToString()).ToString(), relevanceTask.TaskNo); return; } //4、处理任务完成状态 //var isOk = ConfirmTaskFinishToSrm(currentTask, "堆垛机任务完成"); sdaResult = vs.ConfirmTaskFinish((int)currentTask.DeviceId, Convert.ToInt32(currentTask.TaskNo)); if (sdaResult.result) { //using (var tran = dbOrm.Database.BeginTransaction()) //{ //try //{ //堆垛机完成了当前任务后进行任务状态的修改 //ChangeTaskStateWhenTaskFinish(currentTask); currentTask.FinishedTime = DateTime.Now;//完成时间 currentTask.TaskState = (int)SubTaskStateEnum.已完成; var isExist = dbOrm.ware_task_sub.Any(u => u.TaskId == currentTask.TaskId && u.TaskState != (int)SubTaskStateEnum.已完成 && u.Id != currentTask.Id); if (!isExist) { var maintask = dbOrm.ware_task.Where(u => u.Id == currentTask.TaskId).FirstOrDefault(); if (maintask != null) { maintask.TaskState = (int)TaskStateEnum.已完成; } } dbOrm.SaveChanges(); //tran.Commit(); //} //catch (Exception) //{ //tran.Rollback(); // throw; //} //} } } vs.Close(); } catch (Exception ex) { errMsg = $"堆垛机任务完成异常:{ex.Message}"; //SysExceptionInfoHandler.GetExceptionInfoForError("自动结束堆垛机任务线程(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception); //SysExceptionInfoHandler.InsertExceptionInfo(exception, true); } } /// /// 判断是人工发送给任务,单独给堆垛机发送任务完成信号 /// /// /// /// private bool ConfirmTaskFinishToSda(int deviceId, int taskId) { //任务完成处理成功,需要再给堆垛机发送任务完成确认信号 SdaResEntity sdaResult = new SdaResEntity(); try { sdaResult = new SrmService.SrmServiceClient().ConfirmTaskFinish(deviceId, taskId); if (!sdaResult.result) { Log4NetHelper.WriteInfoLog(iWareCommon.Utils.LogType.SrmTheadService, "判断是人工发送的任务,单独给堆垛机发送任务完成信号,【失败】,设备号:" + deviceId + ",任务号:" + taskId); return false; } else { Log4NetHelper.WriteInfoLog(iWareCommon.Utils.LogType.SrmTheadService, "判断是人工发送的任务,单独给堆垛机发送任务完成信号,【成功】,设备号:" + deviceId + ",任务号:" + taskId); return true; } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(iWareCommon.Utils.LogType.SrmTheadService, "判断是人工发送的任务,单独给堆垛机发送任务完成信号,【异常】,设备号:" + deviceId + ",任务号:" + taskId + ",ex:" + ex.Message, ex); throw ex; } } #region 向堆垛机发送任务完成确认信号 /// /// 向堆垛机发送任务完成确认信号 /// /// /// /// /// private bool ConfirmTaskFinishToSrm(ware_task_sub currentTask, string business) { //任务完成处理成功,需要再给堆垛机发送任务完成确认信号 SdaResEntity sdaResult = new SdaResEntity(); string realSourcePlace = ""; string realToPlace = ""; if (currentTask.TaskType == (int)TaskCategoryEnum.InStock) { realSourcePlace = GetRealLocatiomCodeIn(currentTask.SourcePlace); realToPlace = currentTask.ToPlace; } else if (currentTask.TaskType == (int)TaskCategoryEnum.OutStock) { realSourcePlace = currentTask.SourcePlace; realToPlace = GetRealLocatiomCodeOut(currentTask.ToPlace); } try { if (WCSConfigHelper.GetConfig_IsSimulationPLC()) { sdaResult.result = true; } else { sdaResult = new SrmService.SrmServiceClient().ConfirmTaskFinish((int)currentTask.DeviceId, Convert.ToInt32(currentTask.TaskNo)); } if (!sdaResult.result) { //exception.exceptionMsg = string.Format(business + ",需要再给堆垛机发送任务完成确认信号失败,设备号{0} 任务号{1}", (int)currentTask.DeviceId, currentTask.TaskNo); //SysExceptionInfoHandler.InsertExceptionInfo(exception, true); return false; } else { Log4NetHelper.WriteInfoLog(base.currentLogType, string.Format(business + ",再给堆垛机发送任务完成确认信号成功,设备号{0} 任务号{1}", (int)currentTask.DeviceId, currentTask.TaskNo)); return true; } } catch (Exception ex) { throw ex; } } #endregion #endregion #endregion #region 公共处理 ///// ///// 验证RGV站点上是否允许下发堆垛机新任务 ///// ///// ///// ///// ///// ///// true:允许,false:不允许 //private bool ValidateIsAllowNewTaskForRgvStattion(DbModel model, DeviceTaskTypeEnum _DeviceTaskTypeEnum, string realToPlace, ref string errMsg) //{ // MainInOutFlagEnum _MainInOutFlagEnum = GetMainInOutFlagForSrm(_DeviceTaskTypeEnum); // if (_MainInOutFlagEnum == MainInOutFlagEnum.出库) // { // //判断目标点是否有光电占用 // var rgv_stationCode = model.Base_Station.Where(x => x.SrmStationCode == realToPlace).First(); // var isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattion(rgv_stationCode.RgvStationCode); // if (isGD_HasCatogryForRgvStattion) // { // errMsg = "RGV出库口站点" + rgv_stationCode.RgvStationCode + "上面光电显示有货,不允许下发堆垛机的出库任务"; // return false; // } // } // return true; //} /// /// 根据堆垛机任务类型判断出是出库还是入库 /// /// /// private MainInOutFlagEnum GetMainInOutFlagForSrm(DeviceTaskTypeEnum _DeviceTaskTypeEnum) { switch (_DeviceTaskTypeEnum) { case DeviceTaskTypeEnum.组盘入库: case DeviceTaskTypeEnum.空托转运到立体库: return MainInOutFlagEnum.入库; case DeviceTaskTypeEnum.立库空托到拆盘机入口: case DeviceTaskTypeEnum.出库: return MainInOutFlagEnum.出库; } throw new Exception("堆垛机不支持的任务类型" + _DeviceTaskTypeEnum.ToString()); } /// /// 堆垛机任务完成后修改任务状态 /// /// private void ChangeTaskStateWhenTaskFinish(ware_task_sub currentTask) { //堆垛机完成了当前任务后进行任务状态的修改 currentTask.FinishedTime = DateTime.Now;//完成时间 //currentTask.IsFinished = true; currentTask.TaskState = (int)SubTaskStateEnum.已完成; //currentTask.TaskStateName = DeviceTaskStatusEnum.已完成.ToString(); //currentTask.OperationRemark = "已完成"; //currentTask.ModifyTime = DateTime.Now; //currentTask.ModifyBy = SysGloble.WCSSystem; //currentTask.IsLastTask = (int)EYesOrNo.否;//设置不是最新的任务 } /// /// 堆垛机任务完成后,根据堆垛机的任务类型去判断Base_Salver_V_Station 的State /// /// 堆垛机任务类型 /// 原先的Base_Salver_V_Station 的State /// private Salver_V_Station_StateEnum DeviceTaskTypeEnumToC_V_P_StateEnumWhenTaskFinish(DeviceTaskTypeEnum _DeviceTaskTypeEnum, int old_int_C_V_P_StateEnum) { Salver_V_Station_StateEnum old_C_V_P_StateEnum = (Salver_V_Station_StateEnum)Enum.Parse(typeof(Salver_V_Station_StateEnum), old_int_C_V_P_StateEnum.ToString()); Salver_V_Station_StateEnum _C_V_P_StateEnum = old_C_V_P_StateEnum; switch (_DeviceTaskTypeEnum) { case DeviceTaskTypeEnum.组盘入库: _C_V_P_StateEnum = Salver_V_Station_StateEnum.在库物料; break; //case DeviceTaskTypeEnum22.线下其他垛入库: // _C_V_P_StateEnum = C_V_P_StateEnum.在库其他料; // break; //case DeviceTaskTypeEnum22.线下垫板垛入库: // _C_V_P_StateEnum = C_V_P_StateEnum.在库垫板; // break; //case DeviceTaskTypeEnum22.成品料配板完成回库: // _C_V_P_StateEnum = C_V_P_StateEnum.在库成品料; // break; //case DeviceTaskTypeEnum22.待拆垛回库: // _C_V_P_StateEnum = C_V_P_StateEnum.在库待拆垛; // break; //case DeviceTaskTypeEnum22.桁架垫板垛入立库垫板库位: //case DeviceTaskTypeEnum22.锯切垫板垛入立体库: // _C_V_P_StateEnum = C_V_P_StateEnum.在库垫板; // break; //case DeviceTaskTypeEnum22.移库://移库,状态不变 //case DeviceTaskTypeEnum22.成品料上锯切线出库://成品料出库,状态不变 //case DeviceTaskTypeEnum22.垫板上料出库://垫板出库,状态不变 // _C_V_P_StateEnum = old_C_V_P_StateEnum; // break; //case DeviceTaskTypeEnum22.配板原料出库: // _C_V_P_StateEnum = C_V_P_StateEnum.原料配板中; // break; //case DeviceTaskTypeEnum22.人工出库://出库后会将表Base_Salver_V_Station 清掉 // break; } return _C_V_P_StateEnum; } public override bool ValidateDeviceIsAllowSendTask(int int_deviceId, out string errMsg) { if (FormCC.IsSimulationPLC) { errMsg = "模拟PLC"; return true; } //errMsg = ""; if (!base.ValidateDeviceIsAllowSendTask(int_deviceId, out errMsg)) { return false; } using (var srmService = new SrmService.SrmServiceClient()) { SdaResEntity sdaResult = srmService.IsAllowSendTask(int_deviceId, out errMsg); if (sdaResult.result == false) { errMsg = "非自动、有任务未确认或有报警," + sdaResult.resMsg; Log4NetHelper.WriteErrorLog(currentLogType, "验证堆垛机不可以下发新任务,int_deviceId:" + int_deviceId + ",sdaResultStr:" + JsonConvert.SerializeObject(sdaResult)); } return sdaResult.result; } } /// /// 验证堆垛机是否任务完成 /// /// /// private bool ValidateDeviceTaskIsFinsished(int int_deviceId, ware_task_sub _task, int taskId, DeviceTaskTypeEnum _DeviceTaskTypeEnum, bool? isAllowSimulateExecute, out string errMsg) { errMsg = ""; if (WCSConfigHelper.GetConfig_IsSimulationPLC()) { errMsg = "模拟PLC完成或任务要求强制模拟完成"; return true; } SdaResEntity sdaResult = new SrmService.SrmServiceClient().IsTaskFinish(int_deviceId, taskId); if (sdaResult.result == false) { errMsg = "验证堆垛机是否任务完成 失败:" + JsonConvert.SerializeObject(sdaResult); //Log4NetHelper.WriteErrorLog(currentLogType, "验证堆垛机是否任务完成 失败:" + JsonConvert.SerializeObject(sdaResult)); } //switch (_DeviceTaskTypeEnum) //{ // //涉及到最后到输送线的任务,都要再加上输送线的任务是否完成 // case DeviceTaskTypeEnum.组盘入库: // //using (var srmConveyorService = new SrmConveyorService.SrmConveyorServiceClient()) // //{ // // sdaResultStr = srmConveyorService.IsTaskFinish(taskId); // // sdaResult = JsonConvert.DeserializeObject(sdaResultStr); // // if (sdaResult.result == false) // // { // // errMsg = "验证输送线是否任务完成 失败:" + sdaResultStr; // // Log4NetHelper.WriteErrorLog(currentLogType, "验证输送线是否任务完成 失败:" + sdaResultStr); // // } // //} // break; //} return sdaResult.result; } #endregion #region 私有方法 /// /// 验证数据库中是否有任务要处理 /// /// /// /// Rgv设备号 /// /// /// private List ValidateIsExistTaskToDisposeForIssued(DbOrm dbOrm, int int_deviceId, out string errMsg) { errMsg = ""; List partList = new List(); //看同一个设备,是否还有其他正在执行的任务 var partTask = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)SubTaskStateEnum.已下发). OrderBy(x => x.CreatedTime).FirstOrDefault();//按照主任务的顺序升序 if (partTask != null) { errMsg = string.Format("deviceId={0}的正在执行任务,任务ID:" + partTask.Id + ",主任务:" + partTask.TaskId + ",PLC任务号:" + partTask.TaskNo, int_deviceId); return null; } //1、查询 var currTaskList = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && (x.TaskState == (int)SubTaskStateEnum.未开始 || x.TaskState == (int)SubTaskStateEnum.等待下发)).ToList().OrderBy(x => x.CreatedTime).ToList();//按照主任务优先级的升序排序 if (currTaskList == null || currTaskList.Count == 0) { errMsg = "没有需要处理的任务"; return null; } //查找所有AGV任务 var agvTaskList = dbOrm.ware_task_sub.AsNoTracking().Where(u => u.DeviceId == 1099).ToList(); var currentAgvTask = agvTaskList.Find(u => u.TaskState == (int)SubTaskStateEnum.已完成); if (currentAgvTask == null) { //查找AGV执行步骤最高的 currentAgvTask = agvTaskList.OrderByDescending(u => u.TaskState).FirstOrDefault(); } if (currentAgvTask != null) { //currentAgvTask是执行步骤最高的agv,优先下这个的关联任务 var vs = currTaskList.FindAll(u => u.TaskId == currentAgvTask.TaskId).OrderBy(u => u.TaskSequence).FirstOrDefault(); if (vs != null) { if (vs.TaskState == (int)SubTaskStateEnum.等待下发) { errMsg = $"目标点{vs.ToPlace}的堆垛机任务等待下发"; return null; } else { partList.Add(vs); return partList; } } else { //执行步骤最高的agv没有待处理的堆垛机任务 //查找另一个agv任务 var anotherAgvTask = agvTaskList.Find(u => u.TaskId != currentAgvTask.TaskId); if (anotherAgvTask == null) { var temp = currTaskList.Find(u => u.TaskType == (int)TaskCategoryEnum.MoveStock && u.TaskSequence == 1); if (temp != null) { partList.Add(temp); return partList; } errMsg = "没有任务要执行"; return null; } else { var anthorSrmTask = currTaskList.FindAll(u => u.TaskId == anotherAgvTask.TaskId).OrderBy(u => u.TaskSequence).FirstOrDefault(); ; if (anthorSrmTask != null) { if (anthorSrmTask.TaskState == (int)SubTaskStateEnum.等待下发) { errMsg = $"目标点{anthorSrmTask.ToPlace}的堆垛机任务等待下发"; return null; } else { partList.Add(vs); return partList; } } else { errMsg = "没有任务要执行"; return null; } } } } else { var temp = currTaskList.Find(u => u.TaskType == (int)TaskCategoryEnum.MoveStock && u.TaskSequence == 1); if (temp != null) { partList.Add(temp); return partList; } else { return null; } } //查找AGV执行步骤最高的 //var agvTask = dbOrm.ware_task_sub.AsNoTracking().Where(u => u.TaskState > 0 && u.DeviceId == 1099).OrderByDescending(u => u.TaskState).FirstOrDefault(); //ware_task_sub temp = null; //if (agvTask == null) //{ // temp = currTaskList.Find(u => u.TaskType == (int)TaskCategoryEnum.MoveStock); // if (temp == null) // { // errMsg = "agv没有到达,等待下发"; // return null; // } // else // { // partList.Add(temp); // return partList; // } //} //var firstTask = currTaskList.First();//第一个待执行的任务 //var firstTask = currTaskList.Find(u => u.TaskId == agvTask.TaskId); //partList.Add(firstTask); /* //判断如果这个任务是出库任务的话,就再查询第一个待执行的入库任务 DeviceTaskTypeEnum _DeviceTaskTypeEnum = (DeviceTaskTypeEnum)Enum.Parse(typeof(DeviceTaskTypeEnum), firstTask.TaskType.ToString()); //查询 出库和入库的两个任务,优先执行出库任务 【EditBy shaocx,2022-05-09】 MainInOutFlagEnum _MainInOutFlagEnum = GetMainInOutFlagForSrm(_DeviceTaskTypeEnum); if (_MainInOutFlagEnum == MainInOutFlagEnum.出库) { //查询第一个待执行的入库任务 var queryInOutFlag = (int)MainInOutFlagEnum.入库; var fisrtTaskForIn = currTaskList.Where(x => x.InOutFlag == queryInOutFlag).ToList().OrderBy(x => x.CreateTime).FirstOrDefault(); if (fisrtTaskForIn != null) { partList.Add(fisrtTaskForIn); } } */ //return partList; } #endregion } }