Ver Fonte

优化二级品巷道分配

林豪 左 há 3 anos atrás
pai
commit
a39ba31e2a

+ 6 - 11
Projects/永冠OPP/WCS.Service/Extensions/DeviceExtension.cs

@@ -51,17 +51,12 @@ namespace WCS.Service.Extensions
         /// <exception cref="Exception"></exception>
         public bool WhetherToExecute(IstationRequest type = IstationRequest.无)
         {
-            //当前组有一个运行的设备就停止执行
-            if (Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) return true;
-            //设备组中没有设备有光带信息
-            if (!Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态))) return true;
-            ////有光电无任务
-            //if (Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000))
-            //    throw new Exception(LogHelper.SpliceLogMessage("有光电无任务", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常));
-            ////有光电有任务无请求
-            //if (Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000 && (type != IstationRequest.无 && v.Data2.Request != type)))
-            //    throw new Exception(LogHelper.SpliceLogMessage($"有光电有任务无 {type} 请求", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常));
-
+            foreach (var item in Items)
+            {
+                if (item.Data.VoucherNo != item.Data2.VoucherNo) return true;
+                if (item.Data3.Status.HasFlag(StationStatus.运行状态位)) return true;
+                if (!item.Data2.Status.HasFlag(IstationStatus.光电状态)) return true;
+            }
             return false;
         }
 

+ 3 - 5
Projects/永冠OPP/WCS.Service/Extensions/TaskExtension.cs

@@ -20,16 +20,14 @@ namespace WCS.Service.Extensions
         /// </summary>
         /// <param name="tasks"></param>
         /// <returns></returns>
-        public static List<WCS_TASK> GetOutTask(this List<WCS_TASK> tasks)
+        public static Task[] GetOutTask(this List<WCS_TASK> tasks)
         {
-            var taskids = tasks.Select(v => Create<Task>(v))
+            return tasks.Select(v => Create<Task>(v))
                                .OrderBy(v => v.Line)
                                .ThenBy(v => v.Layer)
                                .ThenBy(v => v.Col)
                                .Take(2)
-                               .DistinctBy(v => v.Col)
-                               .Select(v => v.ID);
-            return tasks.Where(v => taskids.Contains(v.ID)).DistinctBy(v => v.SRMSTATION).ToList();
+                               .DistinctBy(v => v.Col).ToArray();
         }
     }
 

+ 19 - 18
Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs

@@ -285,7 +285,7 @@ namespace WCS.Service.Works.SRM
                     //同时对结果进行排序,分组后取第一组任务
                     //TODO:暂时不确定排序后进行分组是否会完全打乱排序,先按照这种按时执行,后续有异常再更改
                     //TODO:暂时维考虑二楼环穿
-                    var item = q.Where(v => db.Default.Set<WCS_TASK>()
+                    var outDepot = q.Where(v => db.Default.Set<WCS_TASK>()
                                         .Where(d => d.TYPE == TaskType.出库)
                                         .Where(d => d.STATUS > TaskStatus.新建)
                                         .Where(d => d.STATUS < TaskStatus.已完成 || taskidList.Contains(d.ID))
@@ -297,34 +297,35 @@ namespace WCS.Service.Works.SRM
                                 .GroupBy(v => v.ADDRTO)
                                 .FirstOrDefault();
 
-                    if (item == null)
+                    if (outDepot == null)
                     {
                         Ltc.Log($"{deviceCode}无出库任务可执行");
                         return;
                     }
                     //获取两个个可执行任务,此时这两个任务的目标地址是一致的
-                    var tasks = item.Select(v => v).ToList().GetOutTask();
+                    var tasks = outDepot.Select(v => v).ToList().GetOutTask();
 
                     //根据任务的目标地址获取对应的设备组
                     var devs = Device.Find($"{tasks.OrderBy(v => v.ADDRTO).FirstOrDefault().ADDRTO}").Create<StationDeviceGroup>().Items.OrderByDescending(v => v.Entity.CODE).ToArray();
                     var dev1 = devs[0];
                     var dev2 = devs[1];
                     if (obj.Data2.Mode_1 != SCMode.远程) return;
-
                     if (obj.Data2.Status_1 != SCRunStatus.空闲) return;
-                    foreach (var task in tasks)
+
+                    for (int i = 0; i < tasks.Length; i++)
                     {
-                        //判断当前任务为二工位还是一工位
-                        var addrFrom = task.ADDRFROM.Split("-");
+                        var item = tasks[i];
+                        var task = db.Default.Set<WCS_TASK>().Find(item.ID);
 
-                        if (addrFrom[1].ToShort().OddNumberOrEven())
+                        //判断当前任务为二工位还是一工位
+                        if (item.Col.OddNumberOrEven())
                         {
                             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 = addrFrom[0].ToShort();
-                            obj.Data.SCol_1 = addrFrom[1].ToShort();
-                            obj.Data.SLayer_1 = addrFrom[2].ToShort();
-                            obj.Data.ELine_1 = task.SRMSTATION.ToShort();
+                            obj.Data.TaskID_1 = item.ID;
+                            obj.Data.SLine_1 = item.Line;
+                            obj.Data.SCol_1 = item.Col;
+                            obj.Data.SLayer_1 = item.Layer;
+                            obj.Data.ELine_1 = item.SRMSTATION.ToShort();
                             obj.Data.ECol_1 = 0;
                             obj.Data.ELayer_1 = 0;
                             obj.Data.VoucherNo_1++;
@@ -333,10 +334,10 @@ namespace WCS.Service.Works.SRM
                         else
                         {
                             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 = addrFrom[0].ToShort();
-                            obj.Data.SCol_2 = addrFrom[1].ToShort();
-                            obj.Data.SLayer_2 = addrFrom[2].ToShort();
+                            obj.Data.TaskID_2 = item.ID;
+                            obj.Data.SLine_2 = item.Line;
+                            obj.Data.SCol_2 = item.Col;
+                            obj.Data.SLayer_2 = item.Layer;
                             obj.Data.ELine_2 = task.SRMSTATION.ToShort();
                             obj.Data.ECol_2 = 0;
                             obj.Data.ELayer_2 = 0;
@@ -354,7 +355,7 @@ namespace WCS.Service.Works.SRM
 
                         db.Default.SaveChanges();
                         Uploader.Upload(db);
-                        if (addrFrom[1].ToShort().OddNumberOrEven())
+                        if (item.Col.OddNumberOrEven())
                         {
                             var msg = $"状态由[{oldTaskSTATUS}]变更为[{task.STATUS}][{obj.Data.SLine_1}-{obj.Data.SCol_1}-{obj.Data.SLayer_1}][{obj.Data.ELine_1}][{obj.Data.VoucherNo_1}]";
                             task.CreateStatusLog(db, msg, this.GetType());

+ 80 - 65
Projects/永冠OPP/WCS.Service/Works/Station/一楼入库.cs

@@ -8,6 +8,7 @@ using WCS.Entity.Protocol;
 using WCS.Entity.Protocol.SRM;
 using WCS.Service.Extensions;
 using WCS.Service.Helpers;
+using WCS.Service.Log;
 
 namespace WCS.Service.Works.Station
 {
@@ -80,76 +81,90 @@ namespace WCS.Service.Works.Station
 
         protected override void Do(StationDeviceGroup obj)
         {
-            var code = obj.Entity.CODE;
-            //当前组有一个运行的设备就停止执行
-            if (obj.WhetherToExecute()) return;
-
-            //获取需要进行巷道分配的设备
-            var devs = obj.TaskedDeviceGetNextAddress() ?? throw new Exception(LogHelper.SpliceLogMessage("无可用任务", obj.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常, GetType()));
-
-            DB.Do(db =>
+            try
             {
-                var taskIds = devs.Select(p => p.Data2.Tasknum);
-                var tasks = db.Default.Set<WCS_TASK>().Where(p => taskIds.Any(v => v == p.ID)).ToList();
-                var res = WMS.GetTunnelList(tasks.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                if (string.IsNullOrEmpty(res.TunnelNum)) throw new Exception(LogHelper.SpliceLogMessage($"WMS未返回巷道", obj.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常, GetType()));
-                var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                List<TunnelInfo> tunnelInfos = new List<TunnelInfo>();
-                foreach (var item in tunnels)
+                var code = obj.Entity.CODE;
+                //当前组有一个运行的设备就停止执行
+                foreach (var item in obj.Items)
                 {
-                    //当前巷道的取货点
-                    var allIn = Device.Where(v => v.Is(DF.一楼SRM取货)) //一楼所有取货点
-                                      .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
-                                      .Select(v => v.CODE)
-                                      .ToList();
-                    var q = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => allIn.Contains(p.NEXT.CODE))) //下一个目标地址包含取货点的设备
-                                  .Select(v => v.Create<StationDevice>()) //取所有可以到达取货点设备的信息
-                                  .Where(v => !v.Data3.Status.HasFlag(StationStatus.运行状态位) && !v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000)//筛选出空闲的路径点,此处因输送机都是一个动力,因此可以先找路径点再找设备组
-                                  .Distinct()
-                                  .FirstOrDefault();//去一次重
-                    if (q == null) continue;
-                    var dev = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => d.MEMBER == q.Entity)).OrderBy(p => p.CODE).FirstOrDefault();
-
-                    tunnelInfos.Add(new TunnelInfo
-                    {
-                        Tunnel = item,
-                        taskIN = dev, //找到放货点设备所在组
-                        SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                    });
+                    var dev = Device.Find(item.Entity.CODE).Create<StationDevice>();
+                    if (dev.Data.VoucherNo != dev.Data2.VoucherNo) return;
+                    if (dev.Data3.Status.HasFlag(StationStatus.运行状态位)) return;
+                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态)) return;
+                    if (dev.Data2.Tasknum > 10000 && dev.Data2.Request != IstationRequest.请求分配目标地址) return;
                 }
-                //筛选出优先级最高的可用巷道
-                var tunnelInfo = tunnelInfos.Where(v => { try { return v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程 && v.SRM.Data2.SRMStatus == SCRunStatus.空闲; } catch { return false; } })
-                                            .OrderBy(v => tunnelNo.IndexOf(v.Tunnel.CODE)).FirstOrDefault();
-                if (tunnelInfo == null) throw new Exception(LogHelper.SpliceLogMessage("无可用巷道", obj.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常, GetType()));
 
-                //开始向设备中写入任务信息
-                foreach (var dev in devs)
+                //获取需要进行巷道分配的设备
+                var devs = obj.TaskedDeviceGetNextAddress() ?? throw new Exception(LogHelper.SpliceLogMessage("无可用任务", obj.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常, GetType()));
+
+                DB.Do(db =>
                 {
-                    var task = tasks.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-                    if ((task.TaskGroupKey.Contains($"{task.WMSTASK}_") || task.TaskGroupKey.Contains($"_{task.WMSTASK}"))) continue;
-                    if (dev.Data2.Goodsend != task.ADDRNEXT.ToShort()) continue;
-                    dev.Data.Tasknum = task.ID;
-                    dev.Data.Goodsstart = Conv_1030.ToShort();
-                    dev.Data.Goodsend = tunnelInfo.taskIN.CODE.Replace("G", "").ToShort();
-                    dev.Data.CmdType = IstationCmdType.分配目标地址;
-                    dev.Data.VoucherNo++;
-
-                    task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                    task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                    task.ADDRNEXT = dev.Data.Goodsend.ToString();
-                    task.TaskGroupKey = res.WMSTaskGroupKey;
-                    task.ADDRTO = task.DEVICE;
-                    db.Default.SaveChanges();
-
-                    var msg = $"下达从{Conv_1030}移动至{dev.Data.Goodsend}的PLC指令。同时将任务分配至[{ task.TUNNEL }]-[{task.DEVICE}]";
-                    msg += $"[{dev.Data.Tasknum}][{Conv_1030}][{dev.Data.Goodsend}][{tunnelInfo.SRM.Entity.CODE}][{dev.Data.VoucherNo}[{dev.Data2.VoucherNo}]";
-
-                    task.CreateStatusLog(db, msg, this.GetType());
-                }
-            });
+                    var taskIds = devs.Select(p => p.Data2.Tasknum);
+                    var tasks = db.Default.Set<WCS_TASK>().Where(p => taskIds.Any(v => v == p.ID)).ToList();
+                    var res = WMS.GetTunnelList(tasks.Select(v => v.WMSTASK.ToString()).ToList(), code);
+                    if (string.IsNullOrEmpty(res.TunnelNum)) throw new Exception(LogHelper.SpliceLogMessage($"WMS未返回巷道", obj.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常, GetType()));
+                    var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
+
+                    var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
+
+                    List<TunnelInfo> tunnelInfos = new List<TunnelInfo>();
+                    foreach (var item in tunnels)
+                    {
+                        //当前巷道的取货点
+                        var allIn = Device.Where(v => v.Is(DF.一楼SRM取货)) //一楼所有取货点
+                                          .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
+                                          .Select(v => v.CODE)
+                                          .ToList();
+                        var q = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => allIn.Contains(p.NEXT.CODE))) //下一个目标地址包含取货点的设备
+                                      .Select(v => v.Create<StationDevice>()) //取所有可以到达取货点设备的信息
+                                      .Where(v => !v.Data3.Status.HasFlag(StationStatus.运行状态位) && !v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000)//筛选出空闲的路径点,此处因输送机都是一个动力,因此可以先找路径点再找设备组
+                                      .Distinct()
+                                      .FirstOrDefault();//去一次重
+                        if (q == null) continue;
+                        var dev = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => d.MEMBER == q.Entity)).OrderBy(p => p.CODE).FirstOrDefault();
+
+                        tunnelInfos.Add(new TunnelInfo
+                        {
+                            Tunnel = item,
+                            taskIN = dev, //找到放货点设备所在组
+                            SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
+                        });
+                    }
+                    //筛选出优先级最高的可用巷道
+                    var tunnelInfo = tunnelInfos.Where(v => { try { return v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程 && v.SRM.Data2.SRMStatus == SCRunStatus.空闲; } catch { return false; } })
+                                                .OrderBy(v => tunnelNo.IndexOf(v.Tunnel.CODE)).FirstOrDefault();
+                    if (tunnelInfo == null) throw new Exception(LogHelper.SpliceLogMessage("无可用巷道", obj.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常, GetType()));
+
+                    //开始向设备中写入任务信息
+                    foreach (var item in devs)
+                    {
+                        var dev = Device.Find(item.Entity.CODE).Create<StationDevice>();
+                        var task = tasks.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
+                        //if (dev.Data2.Goodsend == task.ADDRNEXT.ToShort() && (task.TaskGroupKey.Contains($"{task.WMSTASK}_") || task.TaskGroupKey.Contains($"_{task.WMSTASK}"))) continue;
+                        dev.Data.Tasknum = task.ID;
+                        dev.Data.Goodsstart = Conv_1030.ToShort();
+                        dev.Data.Goodsend = tunnelInfo.taskIN.CODE.Replace("G", "").ToShort();
+                        dev.Data.CmdType = IstationCmdType.分配目标地址;
+                        dev.Data.VoucherNo++;
+
+                        task.DEVICE = tunnelInfo.SRM.Entity.CODE;
+                        task.TUNNEL = tunnelInfo.Tunnel.CODE;
+                        task.ADDRNEXT = dev.Data.Goodsend.ToString();
+                        task.TaskGroupKey = res.WMSTaskGroupKey;
+                        task.ADDRTO = task.DEVICE;
+                        db.Default.SaveChanges();
+
+                        var msg = $"下达从{Conv_1030}移动至{dev.Data.Goodsend}的PLC指令。同时将任务分配至[{ task.TUNNEL }]-[{task.DEVICE}]";
+                        msg += $"[{dev.Data.Tasknum}][{Conv_1030}][{dev.Data.Goodsend}][{tunnelInfo.SRM.Entity.CODE}][{dev.Data.VoucherNo}[{dev.Data2.VoucherNo}]";
+
+                        task.CreateStatusLog(db, msg, this.GetType());
+                    }
+                });
+            }
+            catch (Exception ex)
+            {
+                InfoLog.INFO_ERROR(ex.Message);
+            }
         }
     }