| | |
| | | { |
| | | private readonly ILogger<WMSCruJob> _logger; |
| | | private Timer _timer; |
| | | private Timer _timer2; |
| | | private readonly ITaskService _taskService; |
| | | private readonly ILocationInfoService _locationInfoService; |
| | | private readonly IStockInfoService _stockInfoService; |
| | |
| | | _taskService=taskService; |
| | | } |
| | | private static readonly object _taskProcessLock = new object(); |
| | | private const int TASK_PROCESS_TIMEOUT = 3000; // 3ç§è¶
æ¶ |
| | | private const int TASK_PROCESS_TIMEOUT = 1000; // 2ç§è¶
æ¶ |
| | | private readonly Queue<int> _deviceQueueSC = new Queue<int>(); |
| | | |
| | | public Task StartAsync(CancellationToken cancellationToken) |
| | | { |
| | | _timer = new Timer(DoWorkWheel, null, TimeSpan.Zero, TimeSpan.FromSeconds(3)); |
| | | // åå§å设å¤éåï¼1-5ï¼ |
| | | for (int i = 1; i <= 5; i++) |
| | | { |
| | | _deviceQueueSC.Enqueue(i); |
| | | } |
| | | |
| | | _timer = new Timer(SCProcessNextDevice, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); |
| | | //_timer2 = new Timer(PLCDoDeciceWork, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2)); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | public static List<string> InStationareaList = new List<string>() { "1113", "1114", "1115", "1116", "1117", "1118", "1119", "1120", "1121", "1122" }; |
| | | |
| | | private void DoWorkWheel(object state) |
| | | //å åæºéå |
| | | private void SCProcessNextDevice(object state) |
| | | { |
| | | if (!Monitor.TryEnter(_taskProcessLock, TASK_PROCESS_TIMEOUT)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (!Monitor.TryEnter(_taskProcessLock, TASK_PROCESS_TIMEOUT)) return; |
| | | try |
| | | { |
| | | // å®ä¹ç¶æå¸¸éï¼é¿å
éæ³æ°å |
| | | const int PLC_IN_FINISH = (int)InTaskStatusEnum.PLC_InFinish; |
| | | const int PLC_IN_InNew = (int)InTaskStatusEnum.InNew; |
| | | const int OUT_NEW = (int)OutTaskStatusEnum.OutNew; |
| | | const int SC_OUT_FINISH = (int)OutTaskStatusEnum.SC_OutFinish; |
| | | const int SC_IN_EXECUTING = (int)InTaskStatusEnum.SC_IntExecuting; |
| | | const int SC_OUT_EXECUTING = (int)OutTaskStatusEnum.SC_OutExecuting; |
| | | const int RELOCATION_EXECUTING = (int)RelocationTaskStatusEnum.RelocationExecuting; |
| | | const int PLC_OUT_EXECUTING = (int)OutTaskStatusEnum.PLC_OutExecuting; |
| | | if (_deviceQueueSC.Count == 0) |
| | | return; |
| | | |
| | | // è·åå½å任塿°æ® |
| | | List<Dt_Task> allTasks = _taskService.Repository.QueryData(); |
| | | int deviceId = _deviceQueueSC.Dequeue(); |
| | | |
| | | // è·åå··éè¶
è¿3个任å¡ç路段 |
| | | HashSet<string> excludedRoadways = allTasks |
| | | .Where(x => x.NumberSsuances > 3) |
| | | .Select(x => x.Roadway) |
| | | .Distinct() |
| | | .ToHashSet(); |
| | | |
| | | // è¿æ»¤éè¦å¤ççä»»å¡ |
| | | List<Dt_Task> tasksToProcess = allTasks |
| | | .Where(x => |
| | | (x.TaskStatus == PLC_IN_FINISH || |
| | | x.TaskStatus == OUT_NEW || |
| | | x.TaskStatus == SC_OUT_FINISH || (x.TaskStatus == PLC_IN_InNew && InStationareaList.Contains(x.SourceAddress))) && |
| | | !excludedRoadways.Contains(x.Roadway)) |
| | | .ToList(); |
| | | |
| | | // æç¶æåç»å¤çï¼åå°é夿¥è¯¢ |
| | | ProcessInAndNewTasks(tasksToProcess, allTasks, excludedRoadways); //ä¸åå åæº |
| | | ProcessOutFinishTasks(tasksToProcess, allTasks); //ä¸åè¾éçº¿ä»»å¡ |
| | | ProcessInPalltask(tasksToProcess, allTasks); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"ä»»å¡å¤çå¼å¸¸ï¼{ex.Message}"); |
| | | try |
| | | { |
| | | SCDoDeviceWork(deviceId); |
| | | _deviceQueueSC.Enqueue(deviceId); |
| | | PLCDoDeciceWork(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _deviceQueueSC.Enqueue(deviceId); |
| | | Console.WriteLine($"è®¾å¤ {deviceId} æ§è¡å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | // å¿
须鿾éï¼å¦åä¼å¯¼è´æ»é |
| | | Monitor.Exit(_taskProcessLock); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | private void ProcessInAndNewTasks(List<Dt_Task> tasksToProcess, List<Dt_Task> allTasks, HashSet<string> excludedRoadways) |
| | | //æ§è¡æ¹æ³ |
| | | private void SCDoDeviceWork(int deviceId) |
| | | { |
| | | const int PLC_IN_FINISH = (int)InTaskStatusEnum.PLC_InFinish; |
| | | const int OUT_NEW = (int)OutTaskStatusEnum.OutNew; |
| | | const int SC_IN_EXECUTING = (int)InTaskStatusEnum.SC_IntExecuting; |
| | | const int SC_OUT_EXECUTING = (int)OutTaskStatusEnum.SC_OutExecuting; |
| | | const int RELOCATION_EXECUTING = (int)RelocationTaskStatusEnum.RelocationExecuting; |
| | | const int RELOCCATION_NEW = (int)RelocationTaskStatusEnum.RelocationNew; |
| | | |
| | | var inAndNewTasks = tasksToProcess |
| | | .Where(x => x.TaskStatus == PLC_IN_FINISH || x.TaskStatus == OUT_NEW).OrderBy(x=>x.CreateDate) |
| | | .ToList(); |
| | | if(inAndNewTasks.Count > 0) |
| | | try |
| | | { |
| | | foreach (var task in inAndNewTasks) |
| | | //夿å½åå åæºæ¯å¦ææ§è¡ä»»å¡ |
| | | if (_taskService.CurrentTaskProgress(deviceId.ToString())) return; |
| | | // è·åå½åå åæºä»»å¡ |
| | | List<Dt_Task> taskList = _taskService.GetaskQueue(deviceId.ToString()); |
| | | if (taskList.Count == 0) return; |
| | | |
| | | foreach (Dt_Task task in taskList) |
| | | { |
| | | // æ£æ¥åä¸å··éæ¯å¦ææ£å¨æ§è¡çä»»å¡ |
| | | bool hasExecutingTask = allTasks.Any(x => |
| | | x.TaskId != task.TaskId && |
| | | x.Roadway == task.Roadway && |
| | | (x.TaskStatus == SC_IN_EXECUTING || |
| | | x.TaskStatus == SC_OUT_EXECUTING || |
| | | x.TaskStatus == RELOCATION_EXECUTING)); |
| | | |
| | | if (hasExecutingTask) |
| | | continue; |
| | | |
| | | if (task.TaskStatus == OUT_NEW) |
| | | WebResponseContent webResponse = JudgmentIsRelocations(task); |
| | | if (!webResponse.Status) |
| | | { |
| | | bool SCNewTasks = allTasks.Any(x => x.TaskStatus != OUT_NEW && x.TargetAddress == task.TargetAddress); |
| | | if (SCNewTasks) |
| | | continue; |
| | | WriteLog.Write_Log("WMS_ç§»åºæ
é", $"ç§»åºè¿å失败å
容", "失败", $"ç§»åºå¤±è´¥,åå ï¼{webResponse.Message}"); |
| | | return; |
| | | } |
| | | |
| | | //夿æ¯å¦éè¦ç§»åº |
| | | WebResponseContent webResponse = JudgmentIsRelocations(task); |
| | | if (!webResponse.Status) continue; |
| | | |
| | | |
| | | // ä¸åå åæºä»»å¡ |
| | | WCSginseng result = _taskService.SC_IssueTasks( |
| | | task.TaskId, |
| | | int.Parse(task.Roadway), |
| | |
| | | |
| | | UpdateTaskStatus(task, result, |
| | | successStatus: task.TaskStatus == PLC_IN_FINISH ? SC_IN_EXECUTING : SC_OUT_EXECUTING, 1); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | private void ProcessOutFinishTasks(List<Dt_Task> tasksToProcess, List<Dt_Task> allTasks) |
| | | { |
| | | const int SC_OUT_FINISH = (int)OutTaskStatusEnum.SC_OutFinish; |
| | | const int PLC_OUT_EXECUTING = (int)OutTaskStatusEnum.PLC_OutExecuting; |
| | | |
| | | var outFinishTasks = tasksToProcess |
| | | .Where(x => x.TaskStatus == SC_OUT_FINISH) |
| | | .ToList(); |
| | | if(outFinishTasks.Count > 0) |
| | | catch (Exception ex) |
| | | { |
| | | foreach (var task in outFinishTasks) |
| | | { |
| | | // æ£æ¥åä¸å··éæ¯å¦æå
¶ä»å·²å®æçä»»å¡ |
| | | bool hasOtherFinishTask = allTasks.Any(x => |
| | | x.Roadway == task.Roadway && |
| | | x.TaskStatus == SC_OUT_FINISH && |
| | | x.TaskId != task.TaskId); |
| | | |
| | | if (hasOtherFinishTask) |
| | | continue; |
| | | |
| | | // ä¸åPLCä»»å¡ |
| | | WCSginseng result = _taskService.PLC_IssueTasks( |
| | | task.TaskId, |
| | | int.Parse(task.Roadway), |
| | | task.TaskNum, |
| | | task.PalletCode, |
| | | int.Parse(task.PalletType), |
| | | task.CurrentAddress, |
| | | task.NextAddress, |
| | | ""); |
| | | |
| | | UpdateTaskStatus(task, result, PLC_OUT_EXECUTING, 2); |
| | | } |
| | | Console.WriteLine($"ä»»å¡å¤çå¼å¸¸ï¼{ex.Message}"); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | private void ProcessInPalltask(List<Dt_Task> tasksToProcess, List<Dt_Task> allTasks) |
| | | private void PLCDoDeciceWork() |
| | | { |
| | | const int PLC_IN_InNew = (int)InTaskStatusEnum.InNew; |
| | | const int PLC_PLC_INEXECUTING = (int)InTaskStatusEnum.PLC_InExecuting; |
| | | var outFinishTasks = tasksToProcess |
| | | .Where(x => x.TaskStatus == PLC_IN_InNew && InStationareaList.Contains(x.SourceAddress)) |
| | | .ToList(); |
| | | if(outFinishTasks.Count > 0) |
| | | try |
| | | { |
| | | foreach (var task in outFinishTasks) |
| | | // è·åå½å任塿°æ® |
| | | List<Dt_Task> allTasks = _taskService.GetaskQueuePLC(); |
| | | if (allTasks.Count == 0) return; |
| | | foreach (var task in allTasks) |
| | | { |
| | | // ä¸åPLCä»»å¡ |
| | | WCSginseng result = _taskService.PLC_IssueTasks( |
| | | task.TaskId, |
| | | int.Parse(task.Roadway), |
| | | task.TaskNum, |
| | | task.PalletCode, |
| | | int.Parse(task.PalletType), |
| | | task.CurrentAddress, |
| | | task.NextAddress, |
| | | ""); |
| | | |
| | | UpdateTaskStatus(task, result, PLC_PLC_INEXECUTING, 2); |
| | | WCSginseng result = _taskService.PLC_IssueTasks(task.TaskId, task.WarehouseId, task.TaskNum, task.PalletCode, int.Parse(task.PalletType), task.CurrentAddress, task.NextAddress, ""); |
| | | UpdateTaskStatus(task, result, (int)OutTaskStatusEnum.PLC_OutExecuting, 2); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"å åæºå®æï¼ä¸åè¾é线æ§è¡ä»»å¡å¤±è´¥ï¼ åå : {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | //ä¿®æ¹ç¶æ |
| | | private void UpdateTaskStatus(Dt_Task task, WCSginseng result, int successStatus,int statype) |
| | | { |
| | | if (result.IsSuccess) |
| | |
| | | task.TaskStatus = successStatus; |
| | | if(task.TaskStatus== (int)OutTaskStatusEnum.SC_OutExecuting) |
| | | { |
| | | task.Dispatchertime = DateTime.Now; |
| | | string Result = MesOutTaskStatusEnum.Start.GetDescription(); |
| | | //è°å䏿¸¸ç³»ç»åé¦å¼å§ä»»å¡ |
| | | _taskService.OutStoreDocCallback(task.TaskNum,Result, "æä½æå"); |
| | | }else if(task.TaskStatus == (int)InTaskStatusEnum.PLC_InExecuting) |
| | | { |
| | | string Result = MesInTaskStatusEnum.Start.GetDescription(); |
| | | //è°å䏿¸¸ç³»ç»åé¦å¼å§ä»»å¡ |
| | | _taskService.InStoreDocCallback(task.TaskNum, Result, "æä½æå",task.PalletCode,""); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | task.Remark = result.Message; |
| | | task.NumberSsuances++; |
| | | } |
| | | //task.NumberSsuances++; |
| | | } |
| | | |
| | | _taskService.Repository.UpdateData(task); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public Task StopAsync(CancellationToken cancellationToken) |
| | | { |
| | |
| | | public void Dispose() |
| | | { |
| | | throw new NotImplementedException(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 夿巷éå
ç§»åº |
| | | /// </summary> |
| | | /// <param name="TaskNum"></param> |
| | | /// <param name="SourceAddress"></param> |
| | | /// <returns></returns> |
| | | public WebResponseContent JudgmentIsRelocations(Dt_Task dt_Task) |
| | | { |
| | | const int PLC_IN_FINISH = (int)InTaskStatusEnum.PLC_InFinish; |
| | | const int SC_IN_EXECUTING = (int)InTaskStatusEnum.SC_IntExecuting; |
| | | const int SC_OUT_EXECUTING = (int)OutTaskStatusEnum.SC_OutExecuting; |
| | | WebResponseContent content = new WebResponseContent(); |
| | | try |
| | | { |
| | | string Locationcodeadd = dt_Task.TaskType == (int)TaskTypeEnum.Inbound ? dt_Task.NextAddress: dt_Task.CurrentAddress ; |
| | | |
| | | Dt_LocationInfo dt_Location = _locationInfoService.Repository.QueryData(x => x.LocationCode == Locationcodeadd).FirstOrDefault(); |
| | | if(dt_Location == null) { return content.Error("æªè½æ¥æ¾å°åºä½"); } |
| | | if (dt_Location.Depth == 1 || dt_Location.RoadwayNo == "5") return content.OK(); |
| | | int locrow = judgmentRow(dt_Location.RoadwayNo, dt_Location.Row); |
| | | Dt_LocationInfo shallowLocation = _locationInfoService.Repository.QueryData(x => x.RoadwayNo == dt_Location.RoadwayNo && x.Row == locrow && x.Layer == dt_Location.Layer && x.Column == dt_Location.Column).FirstOrDefault(); |
| | | if (shallowLocation.LocationStatus == (int)LocationStatusEnum.Free) return content.OK(); |
| | | |
| | | |
| | | //夿æ¯å¦æç§»åºä»»å¡ |
| | | var TransferTask = _taskService.Repository.QueryData(x=>x.TaskStatus== (int)RelocationTaskStatusEnum.RelocationNew && x.CurrentAddress== shallowLocation.LocationCode).FirstOrDefault(); |
| | | if(TransferTask != null) |
| | | { |
| | | //è¿è¡ä¸åç»å åæºä»»å¡ |
| | | WCSginseng result = _taskService.SC_IssueTasks( |
| | | TransferTask.TaskId, |
| | | int.Parse(TransferTask.Roadway), |
| | | TransferTask.TaskNum, |
| | | TransferTask.PalletCode, |
| | | int.Parse(TransferTask.PalletType), |
| | | TransferTask.CurrentAddress, |
| | | TransferTask.NextAddress, |
| | | dt_Task.TargetAddress); |
| | | if (result.IsSuccess) |
| | | { |
| | | TransferTask.TaskStatus = (int)RelocationTaskStatusEnum.RelocationExecuting; |
| | | _taskService.UpdateData(TransferTask); |
| | | return content.OK(); |
| | | } |
| | | else |
| | | { |
| | | UpdateTaskStatus(dt_Task, result, |
| | | successStatus: dt_Task.TaskStatus == PLC_IN_FINISH ? SC_IN_EXECUTING : SC_OUT_EXECUTING, 1); |
| | | |
| | | WriteLog.GetLog("夿巷éå
ç§»åº").Write($"ä¸åå åæºä»»å¡å¤±è´¥ï¼åå ï¼{result.Message}", $"çæç§»åºä»»å¡:GenerateTransferTask"); |
| | | return content.Error(); |
| | | } |
| | | } |
| | | |
| | | var CuttTransferTask = _taskService.Repository.QueryData(x => x.TaskStatus == (int)RelocationTaskStatusEnum.RelocationNew).FirstOrDefault(); |
| | | //夿å½åæ¯å¦æç§»åºä»»å¡ |
| | | if (CuttTransferTask!=null) return content.Error(); |
| | | |
| | | |
| | | if (shallowLocation.LocationStatus != (int)LocationStatusEnum.InStock) return content.Error(); |
| | | |
| | | //çæç§»åºä»»å¡ï¼è¿è¡ä¸å |
| | | return content =GenerateTransferTask(shallowLocation.LocationCode); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | WriteLog.GetLog("夿巷éå
ç§»åº").Write($"å¤æç§»åºå¤±è´¥ï¼åå ï¼{ex.Message}", $"夿巷éå
ç§»åºæ¹æ³:JudgmentIsRelocations"); |
| | | return content.Error(); |
| | | |
| | | } |
| | | } |
| | | |
| | | private int judgmentRow(string RoadwayNo,int locrow) |
| | | { |
| | | if (RoadwayNo == "1" || RoadwayNo == "3") |
| | | { |
| | | return locrow == 1 ? 2 : 3; |
| | | } |
| | | else if (RoadwayNo == "2" || RoadwayNo == "4") |
| | | { |
| | | return locrow == 5 ? 6 : 7; |
| | | } |
| | | else |
| | | { |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | public WebResponseContent GenerateTransferTask(string shallowLocation) |
| | | { |
| | | WebResponseContent webResponse=new WebResponseContent(); |
| | | try |
| | | { |
| | | Dt_LocationInfo OriginalLocation = _locationInfoService.Repository.QueryData(x => x.LocationCode == shallowLocation).FirstOrDefault(); |
| | | Dt_StockInfo dt_StockInfo = _stockInfoService.Repository.QueryData(x => x.LocationCode == shallowLocation).FirstOrDefault(); |
| | | Dt_LocationInfo newLocation = _locationInfoService.GetLocation(OriginalLocation.RoadwayNo, OriginalLocation.LocationType); |
| | | List<Dt_LocationInfo> dt_Locations = new List<Dt_LocationInfo>(); |
| | | |
| | | MES_parameter mES_Parame = _taskService.ApplicationChangeStorageLocation(dt_StockInfo.PalletCode, OriginalLocation.LocationCode, newLocation.LocationCode); |
| | | if (mES_Parame != null) |
| | | { |
| | | if (mES_Parame.Result == "Y") |
| | | { |
| | | //è¿è¡çæä»»å¡ï¼ä¸åä»»å¡è³MES |
| | | Dt_Task task = new Dt_Task(); |
| | | task.TaskNum = "0"; |
| | | task.PalletCode = dt_StockInfo.PalletCode; |
| | | task.PalletType = dt_StockInfo.PalletType; |
| | | task.Roadway = OriginalLocation.RoadwayNo; |
| | | task.TaskType = (int)TaskTypeEnum.Relocation; |
| | | task.TaskStatus = (int)RelocationTaskStatusEnum.RelocationNew; |
| | | task.SourceAddress = OriginalLocation.LocationCode; |
| | | task.TargetAddress = newLocation.LocationCode; |
| | | task.CurrentAddress = OriginalLocation.LocationCode; |
| | | task.NextAddress = newLocation.LocationCode; |
| | | task.WarehouseId = OriginalLocation.WarehouseId; |
| | | task.OrderNo = ""; |
| | | task.Grade = 1; |
| | | task.Creater = "MES"; |
| | | task.CreateDate = DateTime.Now; |
| | | |
| | | OriginalLocation.LocationStatus = (int)LocationStatusEnum.Lock; |
| | | newLocation.LocationStatus = (int)LocationStatusEnum.Lock; |
| | | dt_StockInfo.StockStatus = (int)StockStatusEmun.ç§»åºéå®; |
| | | |
| | | dt_Locations.Add(OriginalLocation); |
| | | dt_Locations.Add(newLocation); |
| | | |
| | | _unitOfWorkManage.BeginTran(); |
| | | _taskService.AddData(task); |
| | | _locationInfoService.UpdateData(dt_Locations); |
| | | _stockInfoService.UpdateData(dt_StockInfo); |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | |
| | | return webResponse.Error("å·²çæç§»åºä»»å¡"); |
| | | //è¿è¡ä¸åç»å åæºä»»å¡ |
| | | /*WCSginseng result = _taskService.SC_IssueTasks( |
| | | task.TaskId, |
| | | int.Parse(task.Roadway), |
| | | task.TaskNum, |
| | | task.PalletCode, |
| | | int.Parse(task.PalletType), |
| | | task.CurrentAddress, |
| | | task.NextAddress, |
| | | task.TargetAddress); |
| | | if (result.IsSuccess) |
| | | { |
| | | task.TaskStatus = (int)RelocationTaskStatusEnum.RelocationExecuting; |
| | | _taskService.UpdateData(task); |
| | | return webResponse.OK(); |
| | | } |
| | | else |
| | | { |
| | | WriteLog.GetLog("夿巷éå
ç§»åº").Write($"ä¸åå åæºä»»å¡å¤±è´¥ï¼åå ï¼{result.Message}", $"çæç§»åºä»»å¡:GenerateTransferTask"); |
| | | return webResponse.Error(); |
| | | }*/ |
| | | } |
| | | else |
| | | { |
| | | WriteLog.GetLog("夿巷éå
ç§»åº").Write($"ç³è¯·å¨ä½å¼å¨ï¼MESä¸å
许移å¨", $"çæç§»åºä»»å¡:GenerateTransferTask"); |
| | | return webResponse.Error(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WriteLog.GetLog("夿巷éå
ç§»åº").Write($"ç³è¯·å¨ä½å¼å¨ï¼MESè¿å为空", $"çæç§»åºä»»å¡:GenerateTransferTask"); |
| | | return webResponse.Error(); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | WriteLog.GetLog("夿巷éå
ç§»åº").Write($"çæç§»åºä»»å¡å¤±è´¥ï¼{ex.Message}", $"çæç§»åºä»»å¡:GenerateTransferTask"); |
| | | return webResponse.Error(); |
| | | } |
| | | } |
| | | } |
| | | } |