using iWareCommon; using iWareCommon.Utils; using iWareSql; using System; using System.Collections.Generic; using System.Threading; using System.Linq; using iWareSql.Orm; using System.Threading.Tasks; using iWareCC.ConveyorService; using Newtonsoft.Json; using iWareSql.DataAccess; using iWareModel; using XiGang.Core.Model; using Admin.NET.Core.TaskModule.Enum; using iWareSql.DbOrm; using iWareModel.EnumType.AoSinPublicCommon; using System.Data.Entity.Infrastructure; using System.Windows.Forms; namespace iWareCC { /// /// 立库输送线任务服务线程类 /// public class ConveyorThreadService : DeviceThreadServiceHandle { private static string _namespace = "iWareCC.ConveyorThreadService"; private ConveyorThreadService() { } public ConveyorThreadService(LogType logType) { base.currentLogType = logType; } public override void StartService() { Task.Run(() => { try { //自动执行立库输送线任务线程 Log4NetHelper.WriteInfoLog(base.currentLogType, "[自动执行立库输送线任务线程] 启动了"); ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(DoConveyorsTask)), (int)EDevice.输送线); //自动结束立库输送线任务线程 ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(FinishTask)), (int)EDevice.输送线); //清楚发送完成信号 //ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(ClearComplete)), (int)EDevice.输送线); } catch (Exception ex) { Log4NetHelper.WriteErrorLog(base.currentLogType, "ConveyorThreadService线程启动出现异常", ex); } }); } //#region 线程处理 //#region 自动执行立库输送线任务线程 /// /// 自动执行立库输送线任务 /// /// private void DoConveyorsTask(object deviceId) { string errMsg = ""; while (true) { if (SystemValue.isStartedModel) { DoConveyorsTaskByThead(deviceId, out errMsg); } SystemWarningMsg._lbl_Alert_ConveyerRelease = errMsg; Thread.Sleep(cycleDelay); } } /// /// 自动执行立库输送线任务(线程) /// /// private void DoConveyorsTaskByThead(object deviceId, out string errMsg) { errMsg = ""; try { /* * 执行发送给立库输送线的指令任务 * 1、验证根据设备号是否找到输送线 * 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3 * 3、判断数据库中是否有可要下发的任务,如果有就下发+验证起始点和目标点是否正确 * 4、下发成功后,更新任务状态 */ int int_deviceId = (int)deviceId; //var isOk = ValidateDeviceIsAllowSendTask(int_deviceId, out errMsg); //if (!isOk) //{ // errMsg = "不允许下发新任务," + errMsg; // return; //} var vs = new ConveyerServiceClient(); if (vs.ReadAddress("6900|502.3") || vs.ReadAddress("6900|2.3")) { vs.Close(); errMsg = "不允许下发新任务,等待关门信号"; return; } using (DbOrm dbOrm = new DbOrm()) { #region //3、判断数据库中是否有可要下发的任务,如果有就下发 //var currentTask = ValidateIsExistTaskToDispose(dbOrm, int_deviceId, out errMsg, SubTaskStateEnum.已下发); //查看当前输送线是否有执行的任务 var isExist = dbOrm.ware_task_sub.AsNoTracking().Any(u => u.TaskState != (int)SubTaskStateEnum.未开始 && u.DeviceId == 3); if (isExist) { errMsg = "有执行中的任务不允许下发新任务"; return; } //入库任务由agv线程下发,主要看出库任务 //查看当前执行中的堆垛机任务 var srmtask = dbOrm.ware_task_sub.AsNoTracking().Where(u => u.TaskState != (int)SubTaskStateEnum.未开始 && u.DeviceId == 1 && u.TaskType != 3).FirstOrDefault(); if (srmtask == null) { errMsg = "没有执行中的堆垛机任务不允许下发新任务"; return; } var currentTask = dbOrm.ware_task_sub.Where(u => u.TaskType == (int)TaskCategoryEnum.OutStock && u.TaskId == srmtask.TaskId && u.DeviceId == 3 && u.TaskState == (int)SubTaskStateEnum.未开始).FirstOrDefault(); if (currentTask == null) { errMsg = "没有新任务需要下发"; return; } //验证起始点和目标点是否正确 //RealPlaceEntity realPlaceEntity = null; //if (!ValdiatePalceIsRight(dbOrm, currentTask.SourcePlace, currentTask.ToPlace, ref realPlaceEntity)) return; SdaResEntity sdaResult = new SdaResEntity(); try { if (FormCC.IsSimulationPLC) { sdaResult.result = true; } else { var mainTask = dbOrm.ware_task.AsNoTracking().Where(u => u.Id == currentTask.TaskId).FirstOrDefault(); sdaResult = vs.SendConveyerTask(int_deviceId, Convert.ToInt32(currentTask.TaskNo), currentTask.SourcePlace, currentTask.ToPlace, currentTask.ContainerType.ToString(), Convert.ToString(mainTask.TaskCategory == 4 ? 1 : mainTask.TaskCategory)); } if (sdaResult.result == false) { //给立库输送线下发指令失败 return; } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(currentLogType, $"升降机任务下发异常:{ex.Message}"); return; } #endregion //4、下发成功后,更新任务状态 currentTask.TaskState = (int)SubTaskStateEnum.已下发; currentTask.UpdatedTime = DateTime.Now;//下发时间 dbOrm.SaveChanges(); } vs.Close(); } catch (Exception ex) { } } //#endregion //#region 自动结束立库输送线任务线程 /// /// 自动结束立库输送线任务线程 /// /// private void FinishTask(object deviceId) { string errMsg = ""; while (true) { if (SystemValue.isStartedModel) { FinishConveyorTaskByThead(deviceId, out errMsg); } SystemWarningMsg._lbl_Alert_ConveyerReleaseFinish = errMsg; Thread.Sleep(cycleDelay); } } /// /// 自动结束立库输送线任务线程(线程) /// /// public void FinishConveyorTaskByThead(object deviceId, out string errMsg) { errMsg = ""; try { int int_deviceId = (int)deviceId; var vs = new ConveyerServiceClient(); using (DbOrm dbOrm = new DbOrm()) { var currTasks = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)SubTaskStateEnum.已下发).ToList().OrderBy(x => x.CreatedTime).ToList();//按照主任务优先级的升序排序 if (currTasks == null || currTasks.Count == 0) { return; } foreach (var currentTask in currTasks) { bool isOk = false; if (FormCC.IsSimulationPLC) { isOk = true; } else { //isOk = ValidateDeviceTaskIsFinsished(int_deviceId, currentTask, out errMsg); SdaResEntity sdaResult = vs.IsTaskFinish(int_deviceId, currentTask.SourcePlace, Convert.ToInt32(currentTask.TaskNo)); isOk = sdaResult.result; } if (isOk) { //using (var trans = dbOrm.Database.BeginTransaction()) //{ // try // { //4、更新任务状态 currentTask.TaskState = (int)SubTaskStateEnum.已完成; currentTask.UpdatedTime = DateTime.Now; 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.已完成; } } if (!FormCC.IsSimulationPLC) { var isSendFinish = vs.WriteConveyer_FinishACK(int_deviceId, true, Convert.ToInt32(currentTask.TaskNo), currentTask.SourcePlace); if (!isSendFinish.result) { throw new Exception(string.Format("任务完成处理成功,需要再给立库输送线发送任务完成确认信号失败, 任务号{0}", currentTask.TaskNo)); } } dbOrm.SaveChanges(); // trans.Commit(); // } // catch (Exception) // { // trans.Rollback(); // throw; // } //} } } } vs.Close(); } catch (Exception ex) { Log4NetHelper.WriteErrorLog(currentLogType, $"给输送线完成任务指令出现异常,deviceId:{deviceId},异常:{ex.Message}"); } } //#endregion //#endregion //#region 公共处理 public override bool ValidateDeviceIsAllowSendTask(int int_deviceId, out string errMsg) { errMsg = ""; if (FormCC.IsSimulationPLC) { return true; } //if (!base.ValidateDeviceIsAllowSendTask(int_deviceId, out errMsg)) //{ // return false; //} var vs = new ConveyerServiceClient(); if (vs.ReadAddress("6900|502.3") || vs.ReadAddress("6900|2.3")) { vs.Close(); errMsg = "等待关门信号"; return false; } vs.Close(); return true; } /// /// 验证立库输送线是否任务完成 /// /// /// 0表示没有任务完成,其他表示任务完成,并返回任务号 public override bool ValidateDeviceTaskIsFinsished(int int_deviceId, ware_task_sub task, out string errMsg) { errMsg = ""; SdaResEntity sdaResult = new ConveyerServiceClient().IsTaskFinish(int_deviceId, task.SourcePlace, Convert.ToInt32(task.TaskNo)); //string sdaResultStr = JsonConvert.SerializeObject(sdaResult); if (sdaResult.result == false) { errMsg = sdaResult.resMsg; } return sdaResult.result; //*/ } /// /// 验证立库输送线是否允许任务完成 /// /// /// 0表示没有任务完成,其他表示任务完成,并返回任务号 public bool ValidateDeviceTaskIsAllowFinsished(ware_task_sub task, DbOrm dbOrm) { //Srm_Task srmTask = null; //var queryTaskStatus_HasIssue = (int)ETaskStatus.已下发; //var queryTaskStatus_Finish = (int)ETaskStatus.已完成; //ConveyorTaskTypeEnum taskType = (ConveyorTaskTypeEnum)Enum.Parse(typeof(ConveyorTaskTypeEnum), task.TaskType.ToString()); //switch (taskType) //{ // case ConveyorTaskTypeEnum.配板原料入库: // case ConveyorTaskTypeEnum.线下配板原料入库: // //要判断和他同一个任务的堆垛机任务是不是已经发送任务了,任务状态是 进行中或已完成,如果是就允许完成,如果不是,就不允许完成 // srmTask = dbOrm.Srm_Task.Where(x => x.TaskGuid == task.TaskGuid && ( // x.TaskState == queryTaskStatus_HasIssue || x.TaskState == queryTaskStatus_Finish // )).FirstOrDefault(); // if (srmTask != null) // { // return true; // } // break; // case ConveyorTaskTypeEnum.人工出库: // //要判断和他同一个任务的堆垛机任务是不是已经已完成,如果是就允许完成,如果不是,就不允许完成 // srmTask = dbOrm.Srm_Task.Where(x => x.TaskGuid == task.TaskGuid && ( // x.TaskState == queryTaskStatus_Finish // )).FirstOrDefault(); // if (srmTask != null) // { // return true; // } // break; //} return false; } /// /// 验证立库输送线是否允许任务开始 /// /// /// 0表示没有任务完成,其他表示任务完成,并返回任务号 public bool ValidateDeviceTaskIsAllowStart(ware_task_sub subtask, DbOrm dbOrm) { var queryTaskState1 = (int)SubTaskStateEnum.已完成; //要判断和他同一个任务的且任务优先级高的堆垛机任务是不是已经已完成,如果是就允许开始任务,如果不是,就不允许开始 var srmTask = dbOrm.ware_task_sub.Where(x => x.TaskId == subtask.TaskId && x.TaskSequence < subtask.TaskSequence && x.TaskState != queryTaskState1).FirstOrDefault(); if (srmTask != null) { return false; } return true; } /// /// 验证根据设备号是否找到立库输送线 /// /// /// public override ConveyerView ValidateIsExistDevice(int int_deviceId) { iWareCC.ConveyorService.ConveyerView item = new ConveyorService.ConveyerServiceClient().GetConveyerInfo(int_deviceId); var isExist = item.DeviceId == int_deviceId; if (!isExist) { Log4NetHelper.WriteErrorLog(base.currentLogType, "未找到输送线deviceId=" + int_deviceId); } return (ConveyerView)(object)item; } /* /// /// 验证数据库中是否有任务要处理 /// /// /// /// 立库输送线设备号 /// /// /// public override ware_task_sub ValidateIsExistTaskToDispose(DbOrm dbOrm, int int_deviceId, out string errMsg, TaskExcuteTypeEnum _TaskExcuteTypeEnum) { errMsg = ""; iWareSql.Orm.ware_task_sub currTask = null; switch (_TaskExcuteTypeEnum) { case TaskExcuteTypeEnum.执行任务: var process_count = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)SubTaskStateEnum.已下发).ToList().Count; if (process_count > 0) { errMsg = string.Format("deviceId={0}的正在执行任务", int_deviceId); return default(ware_task_sub); } currTask = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)SubTaskStateEnum.未开始).ToList().OrderBy(x => x.CreatedTime).FirstOrDefault(); break; case TaskExcuteTypeEnum.结束任务: currTask = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)SubTaskStateEnum.已下发).ToList().OrderBy(x => x.CreatedTime).FirstOrDefault(); break; } return (ware_task_sub)(object)currTask; } */ //#endregion } }