Преглед на файлове

堆垛机入库逻辑优化

林豪 左 преди 3 години
родител
ревизия
440ea05a6b
променени са 2 файла, в които са добавени 82 реда и са изтрити 101 реда
  1. 73 100
      Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs
  2. 9 1
      Projects/永冠OPP/WCS.Service/Works/Station/一楼出库.cs

+ 73 - 100
Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs

@@ -7,8 +7,10 @@ using WCS.Core;
 using WCS.Entity;
 using WCS.Entity.Protocol;
 using WCS.Entity.Protocol.SRM;
+using WCS.Service.Entity;
 using WCS.Service.Extensions;
 using WCS.Service.Handlers;
+using WCS.Service.Helpers;
 using WCS.Service.Log;
 
 namespace WCS.Service.Works.SRM
@@ -54,11 +56,10 @@ namespace WCS.Service.Works.SRM
                 }
 
                 if (obj.Data2.SRMMode != SCMode.远程) return;
-
                 if (obj.Data2.SRMStatus != SCRunStatus.空闲) return;
 
-                var isTransfer = new List<WCS_TASK>();
-                WCS_TASK enterPriority = new WCS_TASK(), outPriority = new WCS_TASK();
+                var isTransfer = new List<WCS_TASK>(); //是否有移库任务
+                WCS_TASK enterPriority = new WCS_TASK(), outPriority = new WCS_TASK(); //出入库优先级任务
                 //再检查是否有等待执行的货物
                 DB.Do(db =>
                 {
@@ -136,125 +137,97 @@ namespace WCS.Service.Works.SRM
                     #region 入库
 
                     if (enterPriority != null && outPriority != null && outPriority.Priority > enterPriority.Priority) return;
-                    //获取所有取货点
+
                     var arrIn = obj.GetPickPoint()
-                                   .Where(v => Device.Where(d => d.IsConv())
-                                                     .Select(d => d.Device<IStation521>())
-                                                     .Where(d => d.Data.Goodsend == v.Entity.Code())
-                                                     .Any()).ToList();
+                                   .Where(v => Device.Where(d => d.IsConv()).Select(d => d.Device<IStation521>()).Where(d => d.Data.Goodsend == v.Entity.Code()).Any()) //有正在前往取货点的任务
+                                   .ToList();
+
                     if (!arrIn.Any()) return; //当前堆垛机无入库任务
 
                     //入库口设备信息 找一个有任务有光电且不在运行状态位的取货点 如果找不到代表任务还在输送途中
-                    var st = arrIn.OrderBy(v => v.Data2.Tasknum > 0 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位) ? 0 : 1)
+                    var station = arrIn.OrderBy(v => v.Data2.Tasknum > 0 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位) ? 0 : 1)
                                   .ThenBy(v => v.UpdateTime)
                                   .FirstOrDefault() ?? throw new WarnException($"[{deviceCode}]等待入库任务输送到位");
 
                     //根据上述筛选条件筛选出来的入库任务 找到对应的设备组
-                    var item = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER.CODE == st.Entity.CODE)).Single();
+                    var item = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER.CODE == station.Entity.CODE)).Single();
                     //对数据进行排序,根据CAD图纸规划,取货点两个设备中设备号较大的一个一定对应到堆垛机的一工位货叉
                     //因此按照降序进行排序,可以保证数组中第一个一定是放到堆垛机一工位的数据
                     var devs = item.DEVICEGROUP.Select(v => v.MEMBER)
                                                .Select(v => v.Create<StationDevice>())
                                                .OrderByDescending(v => v.Entity.CODE)
                                                .ToArray();
+                    var finishTaskList = new List<FinishTaskList<int>>(); //成功分配货位的任务
                     //取巷道
                     DB.Do(db =>
                     {
-                        var dev1 = devs[0];
-                        var dev2 = devs[1];
-                        var dev1IsThereATask = dev1.Data2.Tasknum > 0 && dev1.Data2.Status.HasFlag(IstationStatus.光电状态) && !dev1.Data3.Status.HasFlag(StationStatus.运行状态位);
-                        var dev2IsThereATask = dev2.Data2.Tasknum > 0 && dev2.Data2.Status.HasFlag(IstationStatus.光电状态) && !dev2.Data3.Status.HasFlag(StationStatus.运行状态位);
-                        var task1 = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == dev1.Data2.Tasknum);
-                        var task2 = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == dev2.Data2.Tasknum);
-                        if (dev2IsThereATask && dev1IsThereATask && task1.DEVICE != task2.DEVICE) throw new WarnException("同组任务不同巷道");
-
-                        //检测任务数量与可用任务数量是否有效
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == st.Data2.Tasknum) ?? throw new WarnException($"WCS找不到任务号{st.Data2.Tasknum}");
-                        var taskCount = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey && v.TYPE == TaskType.入库);
-
-                        switch (taskCount)
+                        //检测有效任务数与实际任务是是否相等
+                        var validDev = devs.Where(v => v.Data2.Tasknum > 10000 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位));
+                        if (!validDev.Any()) throw new DoException("无有效入库任务");
+                        var tasknum = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == validDev.First().Data2.Tasknum);
+                        var taskList = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == tasknum.TaskGroupKey);
+                        if (validDev.Count() != taskList) throw new WarnException($"任务数量不匹配,设备-{validDev.Count()},WCS-{taskList}");
+
+                        foreach (var dev in validDev)
                         {
-                            case 1:
-                                if (!(dev1IsThereATask || dev2IsThereATask)) throw new WarnException($"任务数量错误");
-
-                                break;
-
-                            case 2:
-                                if (!(dev1IsThereATask && dev2IsThereATask)) throw new WarnException($"任务数量错误");
-                                break;
+                            var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == dev.Data2.Tasknum) ?? throw new WarnException($"设备有光电有任务且不在运行状态,但WCS找不到任务{dev.Data2.Tasknum}");
+                            var oldTask = task.STATUS;
+                            var tunnel = dev.Entity.ROUTES.First().NEXT.CODE;
+                            I_WCS_GetWareCellResponse loc;
+                            //判定当前设备对应的堆垛机工位
+                            if (dev.Entity.CODE == devs[0].Entity.CODE) loc = WMS.GetLocalIn(task.WMSTASK, tunnel, dev.Entity.CODE, Entity.WareCellForkNum.货叉1); //一工位
+                            else if (dev.Entity.CODE == devs[1].Entity.CODE) loc = WMS.GetLocalIn(task.WMSTASK, tunnel, dev.Entity.CODE, Entity.WareCellForkNum.货叉2); //2工位
+                            else throw new WarnException($"设备{dev.Entity.CODE}无法对应至堆垛机的任一一个工位");
 
-                            default: throw new WarnException($"同组任务最多为2,当前任务组有{taskCount},{task.TaskGroupKey}");
-                        }
-
-                        //处理一工位
-                        if (dev1IsThereATask)
-                        {
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-开始:[{obj.Data.TaskID_1}][{obj.Data.SLine_1}][{obj.Data.SCol_1}][{obj.Data.SLayer_1}][{obj.Data.ELine_1}][{obj.Data.VoucherNo_1}]");
-                            var tunnel = dev1.Entity.ROUTES.First().NEXT.CODE;
-
-                            if (task1 == null)
-                                throw new WarnException($"设备有光电有任务且不在运行状态,但WCS找不到任务{dev1.Data2.Tasknum}");
-                            var loc = WMS.GetLocalIn(task1.WMSTASK, tunnel, dev1.Entity.CODE, Entity.WareCellForkNum.货叉1);
-                            var locno = string.Format("{0}-{1}-{2}", loc.Row, loc.Colomn, loc.Layer);
-                            var oldTask = task1.STATUS;
-                            task1.UPDATETIME = DateTime.Now;
-                            task1.STATUS = TaskStatus.堆垛机执行;
-                            task1.ADDRTO = locno;
-                            task1.DEVICE = obj.Entity.CODE;
-                            task1.TUNNEL = tunnel;
-                            db.Default.SaveChanges();
-                            Uploader.Upload(db);
-                            task1.CreateStatusLog(db, $"状态由{oldTask}变更至{task1.STATUS}", this.GetType());
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-开始写入数据-{task1.ID}");
-                            obj.Data.TaskID_1 = task1.ID;
-                            obj.Data.SLine_1 = dev1.Entity.CODE.ToShort();
-                            obj.Data.SCol_1 = 0;
-                            obj.Data.SLayer_1 = 0;
-                            obj.Data.ELine_1 = loc.Row;
-                            obj.Data.ECol_1 = loc.Colomn;
-                            obj.Data.ELayer_1 = loc.Layer;
-                            obj.Data.RES1_1 = (short)taskCount;
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-写入数据结束-{task1.ID}");
-                        }
-                        //处理二工位
-                        if (dev2IsThereATask)
-                        {
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]2工位-开始:[{obj.Data.TaskID_2}][{obj.Data.SLine_2}][{obj.Data.SCol_2}][{obj.Data.SLayer_2}][{obj.Data.ELine_2}][{obj.Data.VoucherNo_2}]");
-                            var tunnel = dev2.Entity.ROUTES.First().NEXT.CODE;
-
-                            if (task2 == null) throw new WarnException($"设备有光电有任务且不在运行状态,但WCS找不到任务{dev2.Data2.Tasknum}");
-                            var loc = WMS.GetLocalIn(task2.WMSTASK, tunnel, dev2.Entity.CODE, Entity.WareCellForkNum.货叉2);
-                            var locno = string.Format("{0}-{1}-{2}", loc.Row, loc.Colomn, loc.Layer);
-                            var oldTask = task2.STATUS;
-                            task2.UPDATETIME = DateTime.Now;
-                            task2.STATUS = TaskStatus.堆垛机执行;
-                            task2.ADDRTO = locno;
-                            task2.DEVICE = obj.Entity.CODE;
-                            task2.TUNNEL = tunnel;
-                            db.Default.SaveChanges();
-                            Uploader.Upload(db);
-                            task2.CreateStatusLog(db, $"状态由{oldTask}变更至{task2.STATUS}", this.GetType());
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]2工位-开始写入数据-{task2.ID}");
-                            obj.Data.TaskID_2 = task2.ID;
-                            obj.Data.SLine_2 = dev2.Entity.CODE.ToShort();
-                            obj.Data.SCol_2 = 0;
-                            obj.Data.SLayer_2 = 0;
-                            obj.Data.ELine_2 = loc.Row;
-                            obj.Data.ECol_2 = loc.Colomn;
-                            obj.Data.ELayer_2 = loc.Layer;
-                            obj.Data.RES1_2 = (short)taskCount;
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-写入数据结束-{task2.ID}");
+                            task.UPDATETIME = DateTime.Now;
+                            task.STATUS = TaskStatus.堆垛机执行;
+                            task.ADDRTO = string.Format("{0}-{1}-{2}", loc.Row, loc.Colomn, loc.Layer);
+                            task.DEVICE = obj.Entity.CODE;
+                            task.TUNNEL = tunnel;
+                            task.CreateStatusLog(db, $"状态由{oldTask}变更至{task.STATUS}", this.GetType());
+                            finishTaskList.Add(new FinishTaskList<int>()
+                            {
+                                FinishCode = task.ID,
+                                Station = dev
+                            });
                         }
-                        if (dev1IsThereATask)
+                        db.Default.SaveChanges();
+                    });
+                    DB.Do(db =>
+                    {
+                        foreach (var finish in finishTaskList)
                         {
-                            obj.Data.VoucherNo_1++;
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-结束:[{obj.Data.TaskID_1}][{obj.Data.SLine_1}][{obj.Data.SCol_1}][{obj.Data.SLayer_1}][{obj.Data.ELine_1}][{obj.Data.VoucherNo_1}]");
+                            var task = db.Default.Set<WCS_TASK>().Find(finish.FinishCode);
+                            var addTo = task.ADDRTO.Split("-");
+                            if (finish.Station.Entity.CODE == devs[0].Entity.CODE)  //一工位
+                            {
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-开始:[{obj.Data.TaskID_1}][{obj.Data.SLine_1}][{obj.Data.SCol_1}][{obj.Data.SLayer_1}][{obj.Data.ELine_1}][{obj.Data.VoucherNo_1}]");
+                                obj.Data.TaskID_1 = task.ID;
+                                obj.Data.SLine_1 = finish.Station.Entity.CODE.ToShort();
+                                obj.Data.SCol_1 = 0;
+                                obj.Data.SLayer_1 = 0;
+                                obj.Data.ELine_1 = addTo[0].ToShort();
+                                obj.Data.ECol_1 = addTo[1].ToShort();
+                                obj.Data.ELayer_1 = addTo[2].ToShort();
+                                obj.Data.RES1_1 = finishTaskList.Count.ToShort();
+                                obj.Data.VoucherNo_1++;
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]1工位-结束:[{obj.Data.TaskID_1}][{obj.Data.SLine_1}][{obj.Data.SCol_1}][{obj.Data.SLayer_1}][{obj.Data.ELine_1}][{obj.Data.VoucherNo_1}]");
+                            }
+                            else if (finish.Station.Entity.CODE == devs[1].Entity.CODE)
+                            {
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]2工位-开始:[{obj.Data.TaskID_2}][{obj.Data.SLine_2}][{obj.Data.SCol_2}][{obj.Data.SLayer_2}][{obj.Data.ELine_2}][{obj.Data.VoucherNo_2}]");
+                                obj.Data.TaskID_2 = task.ID;
+                                obj.Data.SLine_2 = finish.Station.Entity.CODE.ToShort();
+                                obj.Data.SCol_2 = 0;
+                                obj.Data.SLayer_2 = 0;
+                                obj.Data.ELine_2 = addTo[0].ToShort();
+                                obj.Data.ECol_2 = addTo[1].ToShort();
+                                obj.Data.ELayer_2 = addTo[2].ToShort();
+                                obj.Data.RES1_2 = finishTaskList.Count.ToShort();
+                                obj.Data.VoucherNo_2++;
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]2工位-结束:[{obj.Data.TaskID_2}][{obj.Data.SLine_2}][{obj.Data.SCol_2}][{obj.Data.SLayer_2}][{obj.Data.ELine_2}][{obj.Data.VoucherNo_2}]");
+                            }
                         }
-                        if (dev2IsThereATask)
-                        {
-                            obj.Data.VoucherNo_2++;
-                            InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{obj.Entity.CODE}]2工位-结束:[{obj.Data.TaskID_2}][{obj.Data.SLine_2}][{obj.Data.SCol_2}][{obj.Data.SLayer_2}][{obj.Data.ELine_2}][{obj.Data.VoucherNo_2}]");
-                        };
                     });
 
                     #endregion 入库

+ 9 - 1
Projects/永冠OPP/WCS.Service/Works/Station/一楼出库.cs

@@ -14,7 +14,15 @@ namespace WCS.Service.Works.Station
         {
             obj.EX(obj =>
             {
-                obj.WhetherToExecute(IstationRequest.堆垛机放货完成请求目标地址);
+                //正在运行
+                if (obj.Data3.Status.HasFlag(StationStatus.运行状态位)) throw new DoException("运行中");
+                //上一次的任务还未执行
+                if (obj.Data.VoucherNo != obj.Data2.VoucherNo) throw new WarnException($"等待任务[{obj.Data2.Tasknum}]执行");
+                //没有光电
+                if (!obj.Data2.Status.HasFlag(IstationStatus.光电状态)) throw new DoException("无光电"); ;
+                //没有请求
+                if (obj.Data2.Request != IstationRequest.堆垛机放货完成请求目标地址) throw new WarnException($"有光电无堆垛机放货完成请求");
+
                 //找到当前站台为当前设备且任务为堆垛机完成的任务
                 DB.Do(db =>
                 {