| | |
| | | using DocumentFormat.OpenXml.Spreadsheet; |
| | | using Furion.Logging; |
| | | using IoTClient; |
| | | using NewLife.Reflection; |
| | | using WCS.Application.Entity; |
| | | using WCS.Application.Util; |
| | | |
| | | namespace WCS.Application; |
| | |
| | | private static void ShuttleCar(WcsDeviceDto modDevice) |
| | | { |
| | | var plcConn = modDevice.modbusUtil; |
| | | // 四向车状态 0:未空闲,1:空闲,2:异常 3:充电中 |
| | | switch (modDevice.Value.ToString()) |
| | | { |
| | | case "0": |
| | |
| | | sysCacheService.HashAddOrUpdate("AlarmInfo_Car", plcConn.PlcIP, -1); |
| | | var modPosTaskStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "任务状态"); |
| | | var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos); |
| | | //判断读取任务状态是否成功 并且任务状态是1 0:无任务,1:任务完成,2:任务取消,3:任务暂停,4:任务异常 5:任务执行中 |
| | | |
| | | WcsCarTasks carTask2 = null;//null 新任务 not null 路径2任务 |
| | | |
| | | if (resultTaskStatus.IsSucceed && valueTaskStatus == 1) |
| | | { |
| | | var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); |
| | | var (resultTask, valueTask) = plcConn.GetDBValue(modPosTask.PosType, modPosTask.PlcPos); |
| | | string valueTaskStr = Convert.ToString(valueTask); |
| | | string strNo = ""; |
| | | var boNo = dicTaskNo.TryGetValue(modDevice.Id.ToString(), out strNo); |
| | | if (valueTaskStr != "0" && strNo != valueTaskStr) |
| | | //读取任务号 |
| | | int valueTaskStr = Convert.ToInt32(valueTask); |
| | | //获取任务信息 根据 任务号、小车编号 |
| | | var carTask = _db.Queryable<WcsCarTasks>().First(m=>m.IsDelete == false && m.Status == TaskStatusEnum.Doing && m.CarTaskNo == valueTaskStr && m.CarNo == modDevice.PlcIdIP); |
| | | if (carTask == null) |
| | | { |
| | | var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr)); |
| | | if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) |
| | | { |
| | | //12.4出库改成调用WMS完成任务接口;WMS操控PDA托盘下架后,WCS任务状态才完成(避免小车继续跑) |
| | | if (modFinshTask.TaskType == TaskTypeEnum.In) |
| | | { |
| | | modFinshTask.Status = TaskStatusEnum.Complete; |
| | | modFinshTask.FinishDate = DateTime.Now; |
| | | _db.Updateable(modFinshTask).ExecuteCommand(); |
| | | var taskMonitor = new WcsTaskMonitor() |
| | | { |
| | | TaskNo = modFinshTask.TaskNo, |
| | | PlcName = modDevice.Text, |
| | | InteractiveMsg = $"穿梭车反馈任务完成" |
| | | }; |
| | | _db.Insertable(taskMonitor).ExecuteCommand(); |
| | | //下发任务日志 |
| | | HubUtil.PublicTask(modFinshTask.Adapt<WcsTaskOutput>()); |
| | | HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>()); |
| | | } |
| | | HttpService httpService = new HttpService(); |
| | | var requestMode = new TaskRequestWMS() |
| | | { |
| | | TaskNo = modFinshTask.TaskNo, |
| | | PalletNo = modFinshTask.PalletNo, |
| | | TaskType = ((int)modFinshTask.TaskType).ToString(), |
| | | TaskStatus = ((int)TaskStatusEnum.Complete).ToString() |
| | | }; |
| | | var modResponseTask = httpService.RequestTask(requestMode).Result; |
| | | modFinshTask.IsSuccess = TaskSuccessEnum.Success; |
| | | _db.Updateable(modFinshTask).ExecuteCommand(); |
| | | |
| | | if (dicTaskNo.ContainsKey(modDevice.Id.ToString())) |
| | | dicTaskNo.Remove(modDevice.Id.ToString()); |
| | | dicTaskNo.Add(modDevice.Id.ToString(), valueTaskStr); |
| | | } |
| | | var modRests = modDevice.listStation.FirstOrDefault(s => s.Text == "复位"); |
| | | plcConn.SetDBValue(modRests.PosType, modRests.PlcPos, "1");//没有找到任务 复位 |
| | | return; |
| | | } |
| | | |
| | | var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.TaskNo == carTask.TaskNo); |
| | | if (modFinshTask == null) |
| | | { |
| | | break;//没有查询到总任务 |
| | | } |
| | | //获取路径2的任务 下发 |
| | | carTask2 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == carTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.PreId.Contains(carTask.Id.ToString())).OrderBy(m=>m.CreateTime).First(); |
| | | |
| | | if (carTask != null && carTask.Status != TaskStatusEnum.Complete) |
| | | { |
| | | carTask.Status = TaskStatusEnum.Complete; |
| | | carTask.UpdateTime = DateTime.Now; |
| | | _db.Updateable(carTask).ExecuteCommand(); |
| | | //添加任务明细 |
| | | var taskMonitor = new WcsTaskMonitor() |
| | | { |
| | | TaskNo = carTask.TaskNo, |
| | | PlcName = modDevice.Text, |
| | | InteractiveMsg = $"穿梭车反馈任务完成" |
| | | }; |
| | | _db.Insertable(taskMonitor).ExecuteCommand(); |
| | | //下发任务日志 |
| | | |
| | | HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>()); |
| | | } |
| | | //没有路径2的任务 变更总任务信息 |
| | | if (carTask2 == null && modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) |
| | | { |
| | | modFinshTask.Status = TaskStatusEnum.Complete; |
| | | modFinshTask.FinishDate = DateTime.Now; |
| | | _db.Updateable(modFinshTask).ExecuteCommand(); |
| | | |
| | | //反馈WMS系统 任务完成 |
| | | //HttpService httpService = new HttpService(); |
| | | //var requestMode = new TaskRequestWMS() |
| | | //{ |
| | | // TaskNo = modFinshTask.TaskNo, |
| | | // PalletNo = modFinshTask.PalletNo, |
| | | // TaskType = ((int)modFinshTask.TaskType).ToString(), |
| | | // TaskStatus = ((int)TaskStatusEnum.Complete).ToString() |
| | | //}; |
| | | //var modResponseTask = httpService.RequestTask(requestMode).Result; |
| | | //modFinshTask.IsSuccess = TaskSuccessEnum.Success; |
| | | //_db.Updateable(modFinshTask).ExecuteCommand(); |
| | | HubUtil.PublicTask(modFinshTask.Adapt<WcsTaskOutput>()); |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | var modStationX = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(X)"); |
| | | var (resultx, valuex) = plcConn.GetDBValue(modStationX.PosType, modStationX.PlcPos); |
| | | var modStationY = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(Y)"); |
| | |
| | | var modStationZ = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(Z)"); |
| | | var (resultz, valuez) = plcConn.GetDBValue(modStationZ.PosType, modStationZ.PlcPos); |
| | | |
| | | // 获取任务信息 |
| | | var stationStart = ((int)valuex).ToString().PadLeft(2, '0'); |
| | | var stationEnd = ((int)valuez).ToString().PadLeft(2, '0') + "01"; |
| | | var listTask = _db.Queryable<WcsTask>().OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime) |
| | | .Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar |
| | | && s.StartLocate.StartsWith(stationStart) && s.StartLocate.EndsWith(stationEnd)).ToList(); |
| | | var modTask = listTask.FirstOrDefault(); |
| | | //return; |
| | | if (modTask == null) |
| | | return; |
| | | if (modTask.StartLocate == modTask.EndLocate) |
| | | |
| | | WcsTask modTask; |
| | | //要下发路径2任务 |
| | | if (carTask2 != null) |
| | | { |
| | | modTask.Status = TaskStatusEnum.Doing; |
| | | _db.Updateable(modTask).ExecuteCommand(); |
| | | HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); |
| | | modTask = _db.Queryable<WcsTask>().First(s => s.IsDelete == false && s.TaskNo == carTask2.TaskNo && s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar); |
| | | |
| | | carTask2= _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP).OrderBy(m => m.CreateTime).First(); |
| | | } |
| | | else |
| | | { |
| | | // 获取任务信息 |
| | | modTask = _db.Queryable<WcsTask>().Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar).OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime).First(); |
| | | if (modTask == null) |
| | | { |
| | | return; |
| | | } |
| | | carTask2 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP).OrderBy(m => m.CreateTime).First(); |
| | | } |
| | | |
| | | //return; |
| | | if (modTask == null || carTask2 == null) |
| | | { |
| | | //判断小车是否有空闲时间记录 没有:添加 有:判断当前时间与记录时间是否满足5分钟 满足:添加让小车去充电任务 |
| | | return; |
| | | } |
| | | if (modTask.Status == TaskStatusEnum.Doing) |
| | | |
| | | if (carTask2.Status == TaskStatusEnum.Doing) |
| | | { |
| | | Thread.Sleep(3000); |
| | | return; |
| | | } |
| | | //判断当前任务是否还有前置任务未完成 |
| | | var preStrs = carTask2.PreId.Split(';'); |
| | | foreach (var preStr in preStrs) |
| | | { |
| | | if (string.IsNullOrWhiteSpace(preStr)) |
| | | { |
| | | continue; |
| | | } |
| | | var preId = long.Parse(preStr); |
| | | var CarTaskPre = _db.Queryable<WcsCarTasks>().First(m => m.Id == preId); |
| | | if (CarTaskPre.Status <= TaskStatusEnum.Doing) |
| | | { |
| | | return;//前置任务未完成 |
| | | } |
| | | } |
| | | //先复位 |
| | | var modRest = modDevice.listStation.FirstOrDefault(s => s.Text == "复位"); |
| | | plcConn.SetDBValue(modRest.PosType, modRest.PlcPos, "1"); |
| | | |
| | | List<Result> listResult = new List<Result>(); |
| | | //写入任务号Id的末4位,2个小车一起跑有极低概率重复 |
| | | //获取小车任务号 |
| | | var carTaskNo = FourWayCarUtil.GetTaskNo(); |
| | | |
| | | var modWriteTask = modDevice.listStation.FirstOrDefault(s => s.Text == "写入任务号"); |
| | | listResult.Add(plcConn.SetDBValue(modWriteTask.PosType, modWriteTask.PlcPos, modTask.Id.ToString().Substring(modTask.Id.ToString().Length - 4))); |
| | | listResult.Add(plcConn.SetDBValue(modWriteTask.PosType, modWriteTask.PlcPos, carTaskNo.ToString())); |
| | | |
| | | var modNodeX = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标X"); |
| | | var modNodeY = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标Y"); |
| | |
| | | int posY = Convert.ToInt32(modNodeY.PlcPos); |
| | | int posZ = Convert.ToInt32(modNodeZ.PlcPos); |
| | | int posStatus = Convert.ToInt32(modNodeStatus.PlcPos); |
| | | if (Convert.ToInt32(valuey) != Convert.ToInt32(modTask.StartLocate.Substring(2, 2))) |
| | | |
| | | //交互路径 |
| | | var execuPath = carTask2.ExecutionPath.Split(';'); |
| | | if (Convert.ToInt32(valuex) != Convert.ToInt32(execuPath[0].Substring(0, 2)) || Convert.ToInt32(valuey) != Convert.ToInt32(execuPath[0].Substring(2, 2)) || Convert.ToInt32(valuez) != Convert.ToInt32(execuPath[0].Substring(4, 2))) |
| | | { |
| | | //写入小车当前位置 |
| | | listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), Convert.ToString(valuex))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), Convert.ToString(valuey))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), Convert.ToString(valuez))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); |
| | | return; //小车位置与路径起始位置不同 |
| | | ////写入小车当前位置 |
| | | //listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), Convert.ToString(valuex))); |
| | | //listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), Convert.ToString(valuey))); |
| | | //listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), Convert.ToString(valuez))); |
| | | //listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); |
| | | } |
| | | //写入起始位置取货 |
| | | listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), modTask.StartLocate.Substring(0, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), modTask.StartLocate.Substring(2, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), modTask.StartLocate.Substring(4, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "2")); |
| | | //写入目标位置放货 |
| | | listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), modTask.EndLocate.Substring(0, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), modTask.EndLocate.Substring(2, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), modTask.EndLocate.Substring(4, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); |
| | | string endPos = ""; |
| | | if (modTask.StartLocate.Substring(0, 2).ToInt() >= 14) |
| | | endPos = "01"; |
| | | else |
| | | endPos = "21"; |
| | | if (listTask.Count == 1 && modTask.EndLocate.Substring(2, 2) != endPos) |
| | | |
| | | foreach (var ePath in execuPath) |
| | | { |
| | | //如果后续没有任务,就让小车回到原位 |
| | | listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), modTask.EndLocate.Substring(0, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), endPos));//todo:这里位置待定 |
| | | listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), modTask.EndLocate.Substring(4, 2))); |
| | | listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); |
| | | if (string.IsNullOrWhiteSpace(ePath)) |
| | | { |
| | | continue; |
| | | } |
| | | var epathx = ePath.Substring(0, 2); |
| | | var epathy = ePath.Substring(2, 2); |
| | | var epathz = ePath.Substring(4, 2); |
| | | var epathn = ePath.Substring(6, 1); |
| | | //写入交互位置 |
| | | listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), epathx)); |
| | | listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), epathy)); |
| | | listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), epathz)); |
| | | listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), epathn)); |
| | | } |
| | | |
| | | //这里是把后面的坐标全写0(为了防止上次任务坐标没被覆盖) |
| | | while (posX <= 43097) |
| | | { |
| | |
| | | var result = plcConn.SetDBValue(modStart.PosType, modStart.PlcPos, "1"); |
| | | if (result.IsSucceed) |
| | | { |
| | | modTask.Status = TaskStatusEnum.Doing; |
| | | _db.Updateable(modTask).ExecuteCommand(); |
| | | carTask2.Status = TaskStatusEnum.Doing; |
| | | carTask2.CarTaskNo = carTaskNo; |
| | | _db.Updateable(carTask2).ExecuteCommand(); |
| | | //清除小车空闲时间 |
| | | var taskMonitor = new WcsTaskMonitor() |
| | | { |
| | | TaskNo = modTask.TaskNo, |
| | | TaskNo = carTask2.TaskNo, |
| | | PlcName = modDevice.Text, |
| | | InteractiveMsg = $"向穿梭车下发任务{modTask.TaskNo}" |
| | | InteractiveMsg = $"向穿梭车下发任务{carTask2.TaskNo}" |
| | | }; |
| | | _db.Insertable(taskMonitor).ExecuteCommand(); |
| | | //下发任务日志 |
| | | HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); |
| | | HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>()); |
| | | } |
| | | } |
| | |
| | | //小车状态异常 |
| | | var modPosTaskStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "任务状态"); |
| | | var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos); |
| | | |
| | | if (resultTaskStatus.IsSucceed && valueTaskStatus == 1) |
| | | { |
| | | if (resultTaskStatus.IsSucceed && valueTaskStatus == 1) |
| | | var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); |
| | | var (resultTask, valueTask) = plcConn.GetDBValue(modPosTask.PosType, modPosTask.PlcPos); |
| | | string valueTaskStr = Convert.ToString(valueTask); |
| | | string strNo = ""; |
| | | var boNo = dicTaskNo.TryGetValue(modDevice.Id.ToString(), out strNo); |
| | | if (valueTaskStr != "0" && strNo != valueTaskStr) |
| | | { |
| | | var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); |
| | | var (resultTask, valueTask) = plcConn.GetDBValue(modPosTask.PosType, modPosTask.PlcPos); |
| | | string valueTaskStr = Convert.ToString(valueTask); |
| | | string strNo = ""; |
| | | var boNo = dicTaskNo.TryGetValue(modDevice.Id.ToString(), out strNo); |
| | | if (valueTaskStr != "0" && strNo != valueTaskStr) |
| | | var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr)); |
| | | if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) |
| | | { |
| | | var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr)); |
| | | if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) |
| | | HttpService httpService = new HttpService(); |
| | | var requestMode = new TaskRequestWMS() |
| | | { |
| | | HttpService httpService = new HttpService(); |
| | | var requestMode = new TaskRequestWMS() |
| | | { |
| | | TaskNo = modFinshTask.TaskNo, |
| | | PalletNo = modFinshTask.PalletNo, |
| | | TaskType = ((int)modFinshTask.TaskType).ToString(), |
| | | TaskStatus = ((int)TaskStatusEnum.Complete).ToString() |
| | | }; |
| | | var modResponseTask = httpService.RequestTask(requestMode).Result; |
| | | modFinshTask.IsSuccess = TaskSuccessEnum.Success; |
| | | _db.Updateable(modFinshTask).ExecuteCommand(); |
| | | //下发任务日志 |
| | | //HubUtil.PublicTask(modFinshTask.Adapt<WcsTaskOutput>()); |
| | | //HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>()); |
| | | TaskNo = modFinshTask.TaskNo, |
| | | PalletNo = modFinshTask.PalletNo, |
| | | TaskType = ((int)modFinshTask.TaskType).ToString(), |
| | | TaskStatus = ((int)TaskStatusEnum.Complete).ToString() |
| | | }; |
| | | var modResponseTask = httpService.RequestTask(requestMode).Result; |
| | | modFinshTask.IsSuccess = TaskSuccessEnum.Success; |
| | | _db.Updateable(modFinshTask).ExecuteCommand(); |
| | | //下发任务日志 |
| | | //HubUtil.PublicTask(modFinshTask.Adapt<WcsTaskOutput>()); |
| | | //HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>()); |
| | | |
| | | if (dicTaskNo.ContainsKey(modDevice.Id.ToString())) |
| | | dicTaskNo.Remove(modDevice.Id.ToString()); |
| | | dicTaskNo.Add(modDevice.Id.ToString(), valueTaskStr); |
| | | } |
| | | if (dicTaskNo.ContainsKey(modDevice.Id.ToString())) |
| | | dicTaskNo.Remove(modDevice.Id.ToString()); |
| | | dicTaskNo.Add(modDevice.Id.ToString(), valueTaskStr); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | Console.WriteLine($"穿梭车{modDevice.PlcIdIP}异常"); |
| | | var modPosError = modDevice.listStation.FirstOrDefault(s => s.Text == "错误码"); |
| | | var (result, valueError) = plcConn.GetDBValue(modPosError.PosType, modPosError.PlcPos); |
| | |
| | | /// <param name="modDevice"></param> |
| | | private static void AGV(WcsDeviceDto modDevice) |
| | | { |
| | | if (AGVStatus) |
| | | { |
| | | return; |
| | | } |
| | | //这里找出来AGV待执行和正在执行的任务,如果有正在执行的任务就跳出,没有的话就按照优先级下发一个任务给AGV |
| | | var listTask = _db.Queryable<WcsTask>() |
| | | .Where(s => (s.Status == TaskStatusEnum.Doing || s.Status == TaskStatusEnum.Wait) && s.Type == PLCTypeEnum.AGV) |
| | | .OrderBy(s => s.Levels).ToList(); |
| | | |
| | | //这里找出来AGV待执行的任务、按照优先级下发一个任务给AGV |
| | | var listTask = _db.Queryable<WcsTask>().Where(s => (s.Status == TaskStatusEnum.Wait || s.Status == TaskStatusEnum.Doing) && s.Type == PLCTypeEnum.AGV).OrderBy(s => s.Levels).ToList(); |
| | | if (listTask.Count == 0) |
| | | return; |
| | | if (listTask.Any(s => s.Status == TaskStatusEnum.Doing)) |
| | | { |
| | | //有任务执行中 暂不下发任务 |
| | | return; |
| | | } |
| | | //WcsTask modTask = listTask.FirstOrDefault(); |
| | | |
| | | foreach (var modTask in listTask) |
| | | { |
| | | //入缓存区时,检验一下缓存区位置 |
| | | if (modTask.EndLocate.Substring(0, 1) == "Z") |
| | | if (_db.Queryable<WcsTask>().Any(s => s.EndLocate == modTask.EndLocate && s.IsDelete == false && s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.AGV )) |
| | | { |
| | | if (modTask.EndLocate.Substring(1, 1) == "5") |
| | | { |
| | | string end = AGVStorageUtil.GetPalletInStorage(modTask.TaskNo); |
| | | if (end.IsNullOrEmpty()) |
| | | continue; |
| | | if (modTask.EndLocate != end) |
| | | { |
| | | modTask.EndLocate = end; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string end = AGVStorageUtil.GetProductInStorage(modTask.TaskNo); |
| | | if (end.IsNullOrEmpty()) |
| | | continue; |
| | | if (modTask.EndLocate != end) |
| | | { |
| | | modTask.EndLocate = end; |
| | | } |
| | | } |
| | | continue; // 有目的位置一致且正在执行的任务 |
| | | } |
| | | //出缓存区时,检验一下缓存区位置 |
| | | if (modTask.StartLocate.Substring(0, 1) == "Z") |
| | | { |
| | | if (modTask.StartLocate.Substring(1, 1) == "5") |
| | | { |
| | | string start = AGVStorageUtil.GetPalletOutStorage(); |
| | | if (start.IsNullOrEmpty()) |
| | | continue; |
| | | if (modTask.StartLocate != start) |
| | | { |
| | | modTask.StartLocate = start; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | string start = AGVStorageUtil.GetProductOutStorage(); |
| | | if (start.IsNullOrEmpty()) |
| | | continue; |
| | | if (modTask.StartLocate != start) |
| | | { |
| | | modTask.StartLocate = start; |
| | | } |
| | | } |
| | | } |
| | | //把托盘拉到缓存位 先判断这里有没有 |
| | | if (modTask.EndLocate.Substring(0, 1) == "C") |
| | | { |
| | | var bo = _sysConfigService.GetConfigValue<bool>("cache_" + modTask.EndLocate).Result; |
| | | if (bo) |
| | | continue; |
| | | } |
| | | //如果拉托盘去成品工位,先检查有没有缺托 |
| | | if (modTask.StartLocate.Substring(0, 1) == "D" && modTask.EndLocate.Substring(0, 1) == "B") |
| | | { |
| | | //判断目标位置是拆托机的任务有没有,有就跳过拆托机到成品工位的任务 |
| | | if (listTask.Any(s => s.EndLocate.Substring(0, 1) == "D")) |
| | | continue; |
| | | } |
| | | //如果目的工位是原料仓,先检查原料仓储位状态 |
| | | if (modTask.EndLocate == AGVStaionEnum.F1.ToString()) |
| | | { |
| | | if (_sysConfigService.GetConfigValue<bool>("cache_Materal").Result) |
| | | continue; |
| | | } |
| | | //if (modTask.StartLocate == AGVStaionEnum.F1.ToString()) |
| | | //{ |
| | | // if (!_sysConfigService.GetConfigValue<bool>("cache_Materal").Result) |
| | | // continue; |
| | | //} |
| | | |
| | | //如果起始工位是拆托机 |
| | | if (modTask.StartLocate == AGVStaionEnum.D1.ToString()) |
| | | { |
| | | //获取叠拆托机IP |
| | | var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.PalletMachine); |
| | | //获取叠拆托机工位 |
| | | var modDevice2 = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Text == "拆托机"); |
| | | //打开连接 |
| | | var modConn = new PLCUtil(modPlc); |
| | | //是否允许取托信号 |
| | | var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice2.Id && s.Text == "允许取托"); |
| | | var (result, value) = modConn.GetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos); |
| | | if (result.IsSucceed) |
| | | { |
| | | if (value) |
| | | { |
| | | //如果未完成就判断下取托信号有没有写,完成就叫小车取托盘 |
| | | modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice2.Id && s.Text == "取托信号"); |
| | | (result, value) = modConn.GetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos); |
| | | //如果没写入取托信号,就写入 |
| | | if (result.IsSucceed && !value) |
| | | { |
| | | result = modConn.SetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos, "1"); |
| | | WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor() |
| | | { |
| | | TaskNo = modTask.TaskNo, |
| | | PlcId = modDevice2.PlcId, |
| | | PlcName = modPos.PlcPos, |
| | | Status = TaskStatusEnum.Doing, |
| | | InteractiveMsg = $"向{modDevice2.Text}写入取托信号1,结果{result.IsSucceed}", |
| | | }; |
| | | _db.Insertable(modTaskMonitor).ExecuteCommand(); |
| | | HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>()); |
| | | Thread.Sleep(5000); |
| | | } |
| | | break; |
| | | |
| | | } |
| | | else |
| | | { |
| | | //不允许取托,判断是否拆托机准备完成 |
| | | modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice2.Id && s.Text == "准备完成"); |
| | | (result, value) = modConn.GetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos); |
| | | if (!value) |
| | | { |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Console.WriteLine("连接拆托机信号失败"); |
| | | continue; |
| | | } |
| | | } |
| | | //如果目的工位是提升机放货工位,先检查有没有托盘线的任务 |
| | | if (modTask.EndLocate == AGVStaionEnum.A1.ToString()) |
| | | { |
| | | if (_db.Queryable<WcsTask>().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Status == TaskStatusEnum.Doing).Any()) |
| | | continue; |
| | | } |
| | | |
| | | //下发AGV任务 |
| | | AgvTaskInput input = new AgvTaskInput() |
| | | { |
| | | ReqCode = modTask.Id.ToString(), |