林豪 左 2 سال پیش
والد
کامیت
4e220618ed

+ 85 - 0
WCS.Entity/WCS_CacheLine.cs

@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using SqlSugar;
+
+namespace WCS.Entity
+{
+    /// <summary>
+    ///  码垛缓存线主表
+    /// </summary>
+    [SugarTable(nameof(WCS_CacheLine), "码垛缓存线")]
+    public class WCS_CacheLine
+    {
+        /// <summary>
+        ///  ID
+        /// </summary>
+        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "ID")]
+        public int Id { get; set; }
+
+        /// <summary>
+        ///  对应的设备号
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "对应的设备号")]
+        public short LocationNo { get; set; }
+
+        /// <summary>
+        ///  目标地址
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "对应的设备号")]
+        public short TargetAddress { get; set; }
+
+        /// <summary>
+        ///  位信息
+        /// </summary>
+        [Navigate(NavigateType.OneToMany, nameof(WCS_CacheLineLoc.CacheLineId))]
+        public List<WCS_CacheLineLoc> Locations { get; set; }
+
+        /// <summary>
+        ///  要去的行信息对应的ID
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "要去的行信息对应的ID")]
+        public int PalletizingRowId { get; set; }
+
+        /// <summary>
+        ///  要去的行信息
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(PalletizingRowId))]
+        public WCS_PalletizingRow WCS_PalletizingRow { get; set; }
+
+        /// <summary>
+        ///  是否放行
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "是否放行")]
+        public bool Put { get; set; }
+
+        /// <summary>
+        ///  有货数量
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "有货数量")]
+        public int Quantity { get; set; }
+
+        /// <summary>
+        ///  当前线体对应的物料编码组
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "当前线体对应的物料编码组")]
+        public string MatCodeList { get; set; }
+
+        /// <summary>
+        ///  当前线体是否放满货物
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "当前线体是否放满货物")]
+        public bool InStock { get; set; }
+
+        /// <summary>
+        ///  创建时间
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDescription = "创建时间")]
+        public DateTime AddTime { get; set; }
+
+        /// <summary>
+        ///  编辑时间
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDescription = "编辑时间")]
+        public DateTime EditTime { get; set; }
+    }
+}

+ 22 - 4
WCS.WorkEngineering/Modes/WCS_CacheLineLoc.cs → WCS.Entity/WCS_CacheLineLoc.cs

@@ -1,12 +1,12 @@
-using SqlSugar;
-using WCS.Entity;
+using System;
+using SqlSugar;
 
-namespace WCS.WorkEngineering.Modes
+namespace WCS.Entity
 {
     /// <summary>
     ///  码垛缓存线位信息
     /// </summary>
-    [SugarTable(nameof(WCS_CacheLine), "码垛缓存线位信息")]
+    [SugarTable(nameof(WCS_CacheLineLoc), "码垛缓存线位信息")]
     public class WCS_CacheLineLoc
     {
         /// <summary>
@@ -21,6 +21,12 @@ namespace WCS.WorkEngineering.Modes
         [SugarColumn(IsNullable = false, ColumnDescription = "对应的设备号")]
         public short LocationNo { get; set; }
 
+        /// <summary>
+        ///  坐标号
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "坐标号")]
+        public string XYNo { get; set; }
+
         /// <summary>
         /// 物料号
         /// </summary>
@@ -56,5 +62,17 @@ namespace WCS.WorkEngineering.Modes
         /// </summary>
         [SugarColumn(IsNullable = false, ColumnDescription = "是否有货")]
         public bool IsEmpty { get; set; }
+
+        /// <summary>
+        ///  创建时间
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDescription = "创建时间")]
+        public DateTime AddTime { get; set; }
+
+        /// <summary>
+        ///  编辑时间
+        /// </summary>
+        [SugarColumn(IsNullable = true, ColumnDescription = "编辑时间")]
+        public DateTime EditTime { get; set; }
     }
 }

+ 12 - 0
WCS.Entity/WCS_PalletizingRow.cs

@@ -52,6 +52,18 @@ namespace WCS.Entity
         [Navigate(NavigateType.OneToMany, nameof(WCS_PalletizingLoc.PalletizingRowId))]
         public List<WCS_PalletizingLoc> Locs { get; set; }
 
+        /// <summary>
+        ///  行缓存Id
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "任务Id")]
+        public int CacheLineId { get; set; }
+
+        /// <summary>
+        ///  行缓存
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(CacheLineId))]
+        public WCS_CacheLine CacheLine { get; set; }
+
         /// <summary>
         ///  当前所有的物料号
         /// </summary>

+ 3 - 3
WCS.Entity/WCS_TaskInfo.cs

@@ -371,10 +371,10 @@ namespace WCS.Entity
         WaitingToExecute = 1,
 
         /// <summary>
-        /// 分结束
+        /// 分结束
         /// </summary>
-        [Description("分结束")]
-        EndOfShunt = 2,
+        [Description("分结束")]
+        FinishOfShunt = 2,
 
         /// <summary>
         /// 输送机执行中

+ 19 - 0
WCS.WorkEngineering/Extensions/DeviceExtension.cs

@@ -241,6 +241,25 @@ namespace WCS.WorkEngineering.Extensions
             return res.ToArray();
         }
 
+        /// <summary>
+        ///  通过仓库编码获取对应堆垛机信息
+        /// </summary>
+        /// <param name="warehouseCode">仓库编码</param>
+        /// <returns></returns>
+        public static string WarehouseToSrm(this string warehouseCode)
+        {
+            return warehouseCode switch
+            {
+                "1N" => "SRM1",
+                "1S" => "SRM2",
+                "2N" => "SRM3",
+                "2S" => "SRM4",
+                "3N" => "SRM5",
+                "3S" => "SRM6",
+                _ => "Error"
+            };
+        }
+
         #endregion 设备扩展方法
     }
 

+ 0 - 47
WCS.WorkEngineering/Modes/WCS_CacheLine.cs

@@ -1,47 +0,0 @@
-using SqlSugar;
-
-namespace WCS.WorkEngineering.Modes
-{
-    /// <summary>
-    ///  码垛缓存线主表
-    /// </summary>
-    [SugarTable(nameof(WCS_CacheLine), "码垛缓存线")]
-    public class WCS_CacheLine
-    {
-        /// <summary>
-        ///  ID
-        /// </summary>
-        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "ID")]
-        public int Id { get; set; }
-
-        /// <summary>
-        ///  对应的设备号
-        /// </summary>
-        [SugarColumn(IsNullable = false, ColumnDescription = "对应的设备号")]
-        public short LocationNo { get; set; }
-
-        /// <summary>
-        ///  目标地址
-        /// </summary>
-        [SugarColumn(IsNullable = false, ColumnDescription = "对应的设备号")]
-        public short TargetAddress { get; set; }
-
-        /// <summary>
-        ///  位信息
-        /// </summary>
-        [Navigate(NavigateType.OneToMany, nameof(WCS_CacheLineLoc.CacheLineId))]
-        public List<WCS_CacheLineLoc> Locations { get; set; }
-
-        /// <summary>
-        ///  是否放行
-        /// </summary>
-        [SugarColumn(IsNullable = false, ColumnDescription = "是否放行")]
-        public bool Put { get; set; }
-
-        /// <summary>
-        ///  有货数量
-        /// </summary>
-        [SugarColumn(IsNullable = false, ColumnDescription = "有货数量")]
-        public int Quantity { get; set; }
-    }
-}

+ 55 - 55
WCS.WorkEngineering/Systems/分线计算09.cs

@@ -1,5 +1,4 @@
-using Newtonsoft.Json;
-using ServiceCenter.Redis;
+using ServiceCenter.Extensions;
 using ServiceCenter.SqlSugars;
 using System.ComponentModel;
 using WCS.Core;
@@ -45,44 +44,37 @@ namespace WCS.WorkEngineering.Systems
                         _ => "0"
                     };
                     //获取这个地址的下一个地址集合
-                    var cacheLineList = Device.All.First(x => x.Code == nextAdd).Targets;
+                    var cacheLineDevList = Device.All.First(x => x.Code == nextAdd).Targets.Where(x => x.HasFlag(DeviceFlags.桁架缓存放行点));
+                    var cacheLineCodes = cacheLineDevList.Select(x => x.Code.ToShort());
+                    var cacheLineList = db.Queryable<WCS_CacheLine>().Includes(x => x.Locations).ToList();
 
                     #region 跟据缓存信息寻找可以到达的缓存点
 
-                    LineCache line = null;
-                    //检查有没有当前地址可到达缓存点包含了当前工字轮物料号的
-                    foreach (var item in cacheLineList)
-                    {
-                        var key1 = $"{nameof(LineCache)}:{item}";
-                        //有缓存
-                        if (!RedisHub.Default.Exists(key1)) continue;
-                        var lineCache = JsonConvert.DeserializeObject<LineCache>(RedisHub.Default.Get(key1));
-                        //判断缓存是否可以存放当前任务所属的物料号 //TODO:暂未考虑最近一个没有任务绑定的位置不是当前物料的处理方案
-                        if (!lineCache.LineInfos.Any(x => x is { InStock: false, IsEmpty: false } && x.MatCode == taskInfo.MatCode)) continue;
-                        line = lineCache;
-                        break;
-                    }
+                    //找到当前任务可用的缓存线信息
+                    var cacheLine = cacheLineList.Where(x => x.Locations.Any(l => l is { InStock: false, IsEmpty: false })).FirstOrDefault(x => cacheLineCodes.Contains(x.LocationNo) && x.MatCodeList.Contains(taskInfo.MatCode) && !x.InStock);
 
-                    if (line != null)
+                    if (cacheLine != null)//这个任务可以直接去一条线体,不需要新建缓存信息
                     {
-                        var devCode = line.Location;
-                        var lineInfo = line.LineInfos.Where(x => x is { IsEmpty: false, InStock: false }).MinBy(x => x.Index);
-                        foreach (var item in line.LineInfos.OrderBy(x => x.Index))
+                        //找到这条线体中序号最小的一条位信息 非空置且无货
+                        var cacheLoc = cacheLine.Locations.Where(x => x is { InStock: false, IsEmpty: false }).MinBy(x => x.XYNo);
+                        if (cacheLoc != null)
                         {
-                            if (item.Index != lineInfo.Index) continue;
-                            item.TaskNumber = taskInfo.ID;
-                            item.InStock = true;
+                            cacheLoc = db.Queryable<WCS_CacheLineLoc>().Single(x => x.Id == cacheLoc.Id);
+                            cacheLoc.InStock = true;
+                            cacheLoc.TaskId = taskInfo.ID;
+                            cacheLoc.EditTime = DateTime.Now;
+                            db.Updateable(cacheLoc).ExecuteCommand();
+
+                            //WCS任务相关信息
+                            taskInfo.Status = TaskStatus.FinishOfShunt;
+                            taskInfo.AddrNext = cacheLine.LocationNo.ToString();
+                            taskInfo.EditWho = "WCS";
+                            taskInfo.EditTime = DateTime.Now;
+                            taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, $"完成分库计算,目标地址:{cacheLine.LocationNo}");
+                            db.Updateable(taskInfo).ExecuteCommand();
+                            taskInfo.UpdateRedisHash();
+                            return;
                         }
-
-                        taskInfo.Status = TaskStatus.EndOfShunt;
-                        taskInfo.AddrNext = devCode;
-                        taskInfo.EditWho = "WCS";
-                        taskInfo.EditTime = DateTime.Now;
-                        taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, "分线计算");
-                        db.Updateable(taskInfo).ExecuteCommand();
-                        taskInfo.UpdateRedisHash();
-                        RedisHub.Default.Set($"{nameof(LineCache)}:{devCode}", JsonConvert.SerializeObject(line));
-                        return;
                     }
 
                     #endregion 跟据缓存信息寻找可以到达的缓存点
@@ -97,7 +89,7 @@ namespace WCS.WorkEngineering.Systems
                     if (palletizingList.Count <= 0)
                     {
                         taskInfo.InitStackStructure();
-                        break;
+                        return;
                     }
                     foreach (var palletizing in palletizingList)
                     {
@@ -108,68 +100,76 @@ namespace WCS.WorkEngineering.Systems
                             .Where(x => !x.IsEmpty)
                             .Where(x => !x.Finish)
                             .Where(x => x.MatCodeList.Contains(taskInfo.MatCode))
-                            .Where(x => x.Rows.Any(r => r.LineCode == null))
+                            .Where(x => x.Rows.Any(r => r.CacheLineId == 0))
                             .MinBy(x => x.LayerNo);
                         //如果没有哪一层需要这个物料号,就初始化一个新的垛形信息
                         if (palletizingLayer == null)
                         {
                             taskInfo.InitStackStructure();
-                            break;
+                            return;
                         }
 
                         //再找行:未空置、未结束
-                        var palletizingRow = palletizingLayer.Rows.Where(x => x is { IsEmpty: false, Finish: false } && x.MatCodeList.Contains(taskInfo.MatCode) && x.LineCode == null)
+                        var palletizingRow = palletizingLayer.Rows.Where(x => x is { IsEmpty: false, Finish: false } && x.MatCodeList.Contains(taskInfo.MatCode) && x.CacheLineId == 0)
                             .MinBy(x => x.RowNo);
                         //如果没有哪一行需要这个物料号,就初始化一个新的垛形信息
                         if (palletizingRow == null)
                         {
                             taskInfo.InitStackStructure();
-                            break;
+                            return;
                         }
                         //走到这一步就表示没有哪一段线体缓存了当前物料,需要选一段新的线体进行缓存
 
-                        //找出一个redis中没有的缓存位
                         //TODO:暂时不处理就近分线的逻辑
-                        var dev = cacheLineList.Where(x => x.HasFlag(DeviceFlags.桁架缓存放行点)).FirstOrDefault(item => !RedisHub.Default.Exists($"{nameof(LineCache)}:{item}"));
-                        if (dev == null)
+                        //获取一个当前可以使用的分配锁
+                        var devCode = cacheLineDevList.Select(x => x.Code.ToShort()).FirstOrDefault(x => !cacheLineList.Select(s => s.LocationNo).Contains(x));
+                        if (devCode == 0)
                         {
                             World.Log($"无可用线体:{taskInfo.ID}");
                             return;
                         }
 
                         //开始初始化缓存位信息
-                        var cacheLine = new LineCache()
+                        cacheLine = new WCS_CacheLine()
                         {
-                            Location = dev.Code,
-                            LineInfos = new List<LineCacheInfo>()
+                            LocationNo = devCode,
+                            AddTime = DateTime.Now,
+                            PalletizingRowId = palletizingRow.Id,
+                            InStock = false,
+                            Put = false,
+                            MatCodeList = palletizingRow.MatCodeList
                         };
-                        palletizingRow = db.Queryable<WCS_PalletizingRow>().Includes(x => x.Locs).Single(x => x.Id == palletizingRow!.Id);
+
+                        var res = db.Insertable(cacheLine).ExecuteReturnEntity();
+                        palletizingRow = db.Queryable<WCS_PalletizingRow>().Includes(x => x.Locs).Single(x => x.Id == palletizingRow.Id);
                         palletizingRow.Locs = palletizingRow.Locs.OrderBy(x => x.XYNo).ToList();
-                        palletizingRow.LineCode = dev.Targets.FirstOrDefault().Code;
+                        palletizingRow.CacheLineId = res.Id;
                         palletizingRow.EditTime = DateTime.Now;
                         db.Updateable(palletizingRow).ExecuteCommand();
+
                         for (var i = 0; i < palletizingRow.Locs.Count; i++)
                         {
-                            cacheLine.LineInfos.Add(new LineCacheInfo()
+                            var loc = new WCS_CacheLineLoc()
                             {
-                                Index = palletizingRow.Locs[i].XYNo,
+                                XYNo = palletizingRow.Locs[i].XYNo,
                                 InStock = i == 0,
                                 IsEmpty = palletizingRow.Locs[i].IsEmpty,
                                 MatCode = palletizingRow.Locs[i].MatCode,
-                                TaskNumber = i == 0 ? taskInfo.ID : 0,
-                            });
+                                TaskId = i == 0 ? taskInfo.ID : 0,
+                                CacheLineId = res.Id
+                            };
+                            db.Insertable(loc).ExecuteCommand();
                         }
 
-                        taskInfo.Status = TaskStatus.EndOfShunt;
-                        taskInfo.AddrNext = dev.Code;
+                        taskInfo.Status = TaskStatus.FinishOfShunt;
+                        taskInfo.AddrNext = devCode.ToString();
                         taskInfo.EditWho = "WCS";
                         taskInfo.EditTime = DateTime.Now;
-                        taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, "分线计算");
+                        taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, $"完成分库计算,目标地址:{cacheLine.LocationNo}");
                         db.Updateable(taskInfo).ExecuteCommand();
                         taskInfo.UpdateRedisHash();
-                        RedisHub.Default.Set($"{nameof(LineCache)}:{dev.Code}", JsonConvert.SerializeObject(cacheLine));
+                        return;
                     }
-
                     #endregion 初始化一个信息的缓存信息
                 }
             });

+ 1 - 1
WCS.WorkEngineering/Systems/机台叫料生成AGV任务.cs

@@ -22,7 +22,7 @@ namespace WCS.WorkEngineering.Systems
         public override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
 
-            var res = AgvApi.测试路径("LXLK2", "2225552");
+            //var res = AgvApi.测试路径("LXLK2", "2225552");
 
             //if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status)) return;
             //if (!obj.Data3.Status.HasFlag(StationStatus.Auto)) return;

+ 22 - 11
WCS.WorkEngineering/Systems/桁架.cs

@@ -37,21 +37,32 @@ namespace WCS.WorkEngineering.Systems
                 {
                     var db = _db.Default;
                     List<int> ids = new List<int>() { obj.Data2.PalletizingRowId1, obj.Data2.PalletizingRowId2 };
-                    var palletizingRow = db.Queryable<WCS_PalletizingRow>().Includes(x => x.Locs).Where(x => ids.Contains(x.Id)).ToList();
-
-                    //开始更新数据
-                    //更新位数据
-                    foreach (var loc in palletizingRow.SelectMany(x => x.Locs))
-                    {
-                        var pr = db.Queryable<WCS_PalletizingLoc>().Single(x => x.Id == loc.Id);
-                        pr.Finish = true;
-                        db.Updateable(pr).ExecuteCommand();
-                    }
+                    var palletizingRow = db.Queryable<WCS_PalletizingRow>().Includes(x => x.CacheLine, c => c.Locations).Includes(x => x.Locs).Where(x => ids.Contains(x.Id)).ToList();
                     //更新行数据
-                    foreach (var pr in palletizingRow.Select(row => db.Queryable<WCS_PalletizingRow>().Single(x => x.Id == row.Id)))
+                    foreach (var pr in palletizingRow)
                     {
+                        var cacheLine = db.Queryable<WCS_CacheLine>().Includes(x => x.Locations).Single(x => x.Id == pr.CacheLine.Id);
+                        //先更新对应的位信息
+                        try
+                        {
+                            foreach (var loc in pr.Locs)
+                            {
+                                //var cacheLoc = cacheLine.Locations.Single(x => x.XYNo == loc.XYNo);
+                                //cacheLoc = db.Queryable<WCS_CacheLineLoc>().Single(x => x.Id == cacheLoc.Id);
+                                //loc.TaskId = cacheLoc.TaskId;
+                                loc.Finish = true;
+                                db.Updateable(loc).ExecuteCommand();
+                                //db.Deleteable(cacheLoc);s
+                            }
+                        }
+                        catch (Exception a)
+                        {
+                            Console.WriteLine(a);
+                            throw;
+                        }
                         pr.Finish = true;
                         db.Updateable(pr).ExecuteCommand();
+                        db.Deleteable(cacheLine).ExecuteCommand();
                     }
                     //更新层数据
                     var layerId = palletizingRow.FirstOrDefault().PalletizingLayerId;

+ 1 - 1
WCS.WorkEngineering/Systems/桁架分流点.cs

@@ -30,7 +30,7 @@ namespace WCS.WorkEngineering.Systems
             if (obj.Data2.Request != 1) throw new KnownException("无请求", LogLevelEnum.Mid);
 
             var db = new SqlSugarHelper();
-            var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data2.TaskNumber && v.Status == TaskStatus.EndOfShunt) ?? throw new KnownException("未找到对应的WCS任务", LogLevelEnum.Mid);
+            var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data2.TaskNumber && v.Status == TaskStatus.FinishOfShunt) ?? throw new KnownException("未找到对应的WCS任务", LogLevelEnum.Mid);
 
             obj.Data.TaskNumber = obj.Data2.TaskNumber;
             obj.Data.GoodsStart = obj.Entity.Code.ToShort();

+ 47 - 33
WCS.WorkEngineering/Systems/桁架缓存放行点.cs

@@ -1,7 +1,5 @@
-using Newtonsoft.Json;
-using ServiceCenter.Extensions;
+using ServiceCenter.Extensions;
 using ServiceCenter.Logs;
-using ServiceCenter.Redis;
 using ServiceCenter.SqlSugars;
 using System.ComponentModel;
 using WCS.Core;
@@ -9,7 +7,6 @@ using WCS.Entity;
 using WCS.WorkEngineering.Extensions;
 using WCS.WorkEngineering.Protocol.Station;
 using WCS.WorkEngineering.Worlds;
-using TaskStatus = WCS.Entity.TaskStatus;
 
 namespace WCS.WorkEngineering.Systems
 {
@@ -28,17 +25,6 @@ namespace WCS.WorkEngineering.Systems
 
         public override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
-            //清空放行指令
-            if (obj.Data.CmdType == 1)
-            {
-                var devs = _cacheDevices.FirstOrDefault(x => x.Key.Entity.Code == obj.Entity.Code).Value;
-                //当前线体五个缓存位都光电和任务号的数量为0,即无货
-                if (devs.Count(x => x.Data.TaskNumber > 0 || x.Data2.Status.HasFlag(StationStatus.PH_Status) || x.Data2.Status.HasFlag(StationStatus.Run)) == 0)
-                {
-                    obj.Data.CmdType = 0;
-                }
-            }
-
             if (obj.Data.VoucherNo != obj.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.High);
             var nextDev = new Device<IStation524, IStation523>(obj.Entity.Targets.FirstOrDefault()!, World);
             if (nextDev.Data2.Status1.HasFlag(StationStatus1.IsLock)) return;
@@ -49,42 +35,70 @@ namespace WCS.WorkEngineering.Systems
             if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status)) throw new KnownException("无光电", LogLevelEnum.Mid);
             if (obj.Data2.Request != 1) throw new KnownException("无请求", LogLevelEnum.Mid);
 
-            var key = $"{nameof(LineCache)}:{obj.Entity.Code}";
-            if (obj.Data.CmdType == 0)
+            //获取当前缓存线信息对应设备号的下一个地址
+            var devCode = Device.All.Single(x => x.Code == obj.Entity.Code).Targets.FirstOrDefault();
+            var nextCode = obj.Entity.Targets.FirstOrDefault().Code.ToShort();
+
+            #region 计算当前缓存线是否已全部分配任务
+
+            SqlSugarHelper.Do(_db =>
             {
-                var lineCache = JsonConvert.DeserializeObject<LineCache>(RedisHub.Default.Get(key));
-                //检测当前缓存点是否能放行 没有不空置&&未放货
-                if (lineCache.LineInfos.Any(x => x is { IsEmpty: false, InStock: false })) return;
-                //检测实物数量与有货总数是否相等
-                var qty = lineCache.LineInfos.Count(x => x is { IsEmpty: false, InStock: true });
-                var devQty = _cacheDevices.FirstOrDefault(x => x.Key.Entity.Code == obj.Entity.Code).Value
-                    .Count(x => x.Data2.Status.HasFlag(StationStatus.PH_Status));
-                if (qty != devQty) return;
-            }
+                var db = _db.Default;
+                var cacheLine = db.Queryable<WCS_CacheLine>().Includes(x => x.Locations).Single(x => x.LocationNo == obj.Entity.Code.ToShort());
+                //是否所有的位已全部分配位置
+                if (cacheLine != null && cacheLine.Locations.All(x => x is { IsEmpty: false, InStock: true }))
+                {
+                    //判断下一个地址当前是否有对应的任务
+                    if (db.Queryable<WCS_CacheLine>().Any(x => x.LocationNo == nextCode)) return;
+                    //没有对应的任务,开始释放缓存先
+                    cacheLine.InStock = true;
+                    cacheLine.LocationNo = devCode.Code.ToShort();
+                    cacheLine.EditTime = DateTime.Now;
+                    db.Updateable(cacheLine).ExecuteCommand();
+                }
+            });
+
+            #endregion 计算当前缓存线是否已全部分配任务
 
             WCS_TaskInfo task = null;
             SqlSugarHelper.Do(_db =>
             {
                 var db = _db.Default;
-                var taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data2.TaskNumber && v.Status == TaskStatus.EndOfShunt) ?? throw new KnownException("未找到对应的WCS任务", LogLevelEnum.Mid);
-                taskInfo.Status = TaskStatus.ConveyorExecution;
+                //先找到下一个地址对应的缓存信息
+                var lineCache = db.Queryable<WCS_CacheLine>().Includes(x => x.Locations).Single(x => x.LocationNo == nextCode && x.Locations.Any(s => s.TaskId == obj.Data2.TaskNumber));
+                if (lineCache == null) return; //找不到表示当前线体的任务组没有凑齐
+
+                //检测实物数量与有货总数是否相等
+                if (!lineCache.Put)
+                {
+                    var qty = lineCache.Locations.Count(x => x is { IsEmpty: false, InStock: true });
+                    var devQty = _cacheDevices.FirstOrDefault(x => x.Key.Entity.Code == obj.Entity.Code).Value
+                        .Count(x => x.Data2.Status.HasFlag(StationStatus.PH_Status));
+                    if (qty != devQty) return; //表示当前货物未全部到位
+                    lineCache.Put = true;
+                    db.Updateable(lineCache).ExecuteCommand();
+
+                    var pr = db.Queryable<WCS_PalletizingRow>().Single(x => x.Id == lineCache.PalletizingRowId);
+                    pr.LineCode = lineCache.LocationNo.ToString();
+                    db.Updateable(pr).ExecuteCommand();
+                }
+
+                var taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data2.TaskNumber && v.Status == Entity.TaskStatus.FinishOfShunt) ?? throw new KnownException("未找到对应的WCS任务", LogLevelEnum.Mid);
+                taskInfo.Status = Entity.TaskStatus.ConveyorExecution;
                 taskInfo.AddrNext = obj.Entity.Targets.FirstOrDefault().Code;
                 taskInfo.EditWho = "WCS";
                 taskInfo.EditTime = DateTime.Now;
 
-                taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, "桁架缓存方向");
+                taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, "桁架缓存放行");
                 db.Updateable(taskInfo).ExecuteCommand();
                 taskInfo.UpdateRedisHash();
                 task = taskInfo;
             });
-
+            if (task == null) return;
             obj.Data.TaskNumber = obj.Data2.TaskNumber;
             obj.Data.GoodsStart = obj.Entity.Code.ToShort();
             obj.Data.GoodsEnd = task.AddrNext.ToShort();
             obj.Data.VoucherNo++;
-            //当前缓存线默认放行
-            obj.Data.CmdType = 1;//标识放行指令
-            RedisHub.Default.Del(key);
         }
 
         public override bool Select(Device dev)

+ 4 - 12
WCS.WorkEngineering/Systems/满轮主线预写入目标地址.cs

@@ -45,16 +45,8 @@ namespace WCS.WorkEngineering.Systems
                     continue;
                 }
                 var mainlineDiversion = JsonConvert.DeserializeObject<MainlineDiversion>(value);
-                var nextAdd = mainlineDiversion.WarehouseCode switch
-                {
-                    "1N" => 418,
-                    "1S" => 0,
-                    "2N" => 0,
-                    "2S" => 0,
-                    "3N" => 0,
-                    "3S" => 0,
-                    _ => 0
-                };
+                var srmCode = mainlineDiversion.WarehouseCode.WarehouseToSrm();
+                var next = DevicePath.GetPath(obj.Entity.Code, srmCode).Points[1].Code;
 
                 //开始检查任务信息
                 var db = new SqlSugarHelper();
@@ -71,7 +63,7 @@ namespace WCS.WorkEngineering.Systems
                     task.Status = TaskStatus.WaitingToExecute;
                     task.EditWho = "WCS";
                     task.EditTime = DateTime.Now;
-                    task.AddWCS_TASK_DTL(db, obj.Entity.Code, nextAdd.ToString(), "任务完成预分流");
+                    task.AddWCS_TASK_DTL(db, obj.Entity.Code, next.ToString(), "任务完成预分流");
                     db.Default.Updateable(task).ExecuteCommand();
                     db.Connect.CommitTran();
 
@@ -87,7 +79,7 @@ namespace WCS.WorkEngineering.Systems
                 //开始赋值
                 obj.Data3.GetType().GetProperty($"BcrCode{obj.Data3.NextIndex}").SetValue(obj.Data3, bcrCode);
                 obj.Data3.GetType().GetProperty($"TaskNumber{obj.Data3.NextIndex}").SetValue(obj.Data3, task.ID);
-                obj.Data3.GetType().GetProperty($"GoodsEnd{obj.Data3.NextIndex}").SetValue(obj.Data3, nextAdd.ToShort());
+                obj.Data3.GetType().GetProperty($"GoodsEnd{obj.Data3.NextIndex}").SetValue(obj.Data3, next.ToShort());
                 if (obj.Data3.NextIndex >= 49)
                 {
                     obj.Data3.NextIndex = 0;

+ 1 - 1
WCS.WorkEngineering/Systems/环形库分流点.cs

@@ -40,7 +40,7 @@ namespace WCS.WorkEngineering.Systems
             }
 
             var db = new SqlSugarHelper();
-            var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data2.TaskNumber && v.Status == TaskStatus.EndOfShunt) ?? throw new KnownException("未找到对应的WCS任务", LogLevelEnum.Mid);
+            var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data2.TaskNumber && v.Status == TaskStatus.FinishOfShunt) ?? throw new KnownException("未找到对应的WCS任务", LogLevelEnum.Mid);
             try
             {
                 db.Connect.BeginTran();

+ 2 - 2
WCS.WorkEngineering/Systems/码垛区补空托盘任务生成.cs

@@ -30,10 +30,10 @@ namespace WCS.WorkEngineering.Systems
                 //取一个时间最靠前的,没有绑定码垛工位的码垛记录
                 var palletizingInfo = db.Queryable<WCS_Palletizing>().First(x => x.PalletizingStation == null);
                 if (palletizingInfo == null) return;
-                var palleTask = db.Queryable<WCS_TaskInfo>().First(x => x.ID == palletizingInfo.TaskId && (x.Status == TaskStatus.EndOfShunt || x.Status == TaskStatus.ConveyorExecution));
+                var palleTask = db.Queryable<WCS_TaskInfo>().First(x => x.ID == palletizingInfo.TaskId && (x.Status == TaskStatus.FinishOfShunt || x.Status == TaskStatus.ConveyorExecution));
                 if (palleTask == null) return;
                 //获取可以使用的放货站台信息
-                var taskAddNext = Device.All.FirstOrDefault(x => x.Code == palleTask.AddrNext).Targets;
+                var taskAddNext = Device.All.FirstOrDefault(x => x.Code == palleTask.AddrNext).Targets.FirstOrDefault().Targets.FirstOrDefault().Targets;
                 if (taskAddNext == null) return;
                 var devs = Device.All.Where(x => taskAddNext.Contains(x)).Select(x => new Device<IStation520, IStation521, IStation523>(x, World)).ToList();
                 //取一个可用用于码垛的地方

+ 99 - 133
WCS.WorkEngineering/WorkStart.cs

@@ -370,161 +370,125 @@ namespace WCS.WorkEngineering
 
             #region 分拣库一
 
-            //routeInfos.AddRange(new List<RouteInfo>() {
-            //    #region 出库路径
-
-            //    //堆垛机--巷道
-            //    new RouteInfo("SRM1", new string[] { "TY1" }),
-            //    new RouteInfo("SRM2", new string[] { "TY2" }),
-            //    //巷道--一楼堆垛机放货口
-            //    new RouteInfo("TY1", new string[] { "2532" }), //人工取货口
-            //    new RouteInfo("TY2", new string[] { "2732" }),
-            //    new RouteInfo("TY1", new string[] { "2534","2533" }),//AGV取货口
-            //    new RouteInfo("TY2", new string[] { "2734","2733" }),
-            //    //巷道--二楼堆垛机放货口
-            //    new RouteInfo("TY1", new string[] { "1601","1605" }),
-            //    new RouteInfo("TY2", new string[] { "1611","1615" }),
-            //    //二楼堆垛机放货口--二楼拆盘机
-            //    new RouteInfo("1601", new string[] { "1602" }),//非09拆盘机
-            //    new RouteInfo("1611", new string[] { "1612"}),
-            //    new RouteInfo("1605", new string[] { "1606" }),//09拆盘机
-            //    new RouteInfo("1615", new string[] { "1616" }),
-            //    //二楼拆盘机--RGV
-
-            //    //RGV--码垛区域
-            //    new RouteInfo("1601", new string[] { "1661","1666" }),//非09拆盘机
-            //    new RouteInfo("1611", new string[] { }),
-            //    new RouteInfo("1606", new string[] { "1662","1663","1664","1665", "1670","1671","1672","1673","1674","1675"}),//桁架北区码垛站台
-            //    new RouteInfo("1616", new string[] { }),
-
-            //    #endregion 出库路径
-            //});
-
-            #endregion 分拣库一
-
-            #region 出库路线
+            routeInfos.AddRange(new List<RouteInfo>() {
 
-            #region 堆垛机的下一个地址 巷道
+                #region 出库路径
 
-            routeInfos.AddRange(new List<RouteInfo>() {
+                //堆垛机--巷道
                 new RouteInfo("SRM1", new string[] { "TY1" }),
                 new RouteInfo("SRM2", new string[] { "TY2" }),
-            });
-
-            #endregion 堆垛机的下一个地址 巷道
-
-            #region 巷道的下一个地址 堆垛机放货点
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-                  new RouteInfo("TY1", new string[] { "SRM1", "2532", "1601", "1605","2534" }),
-                  new RouteInfo("TY2", new string[] { "SRM2", "2732" }),
-            });
-
-            #endregion 巷道的下一个地址 堆垛机放货点
-
-            #region 堆垛机放货点的下一个地址 拆盘机
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-                   new RouteInfo("1601", new string[] { "1602" }),
-                   new RouteInfo("1605", new string[] { "1606" }),
-            });
-
-            #endregion 堆垛机放货点的下一个地址 拆盘机
-
-            #region 拆盘机的下一个地址 RGV
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-                   new RouteInfo("1602", new string[] { "RGV1" }),
-                   new RouteInfo("1606", new string[] { "RGV1" })
-            });
-
-            #endregion 拆盘机的下一个地址 RGV
-
-            #region RGV的下一个地址 码垛工位
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-                new RouteInfo("1604", new string[] { "1603" }),
-            });
-
-            #endregion RGV的下一个地址 码垛工位
-
-            #endregion 出库路线
-
-            #region 入库路线
-
-            #region 堆垛机取货点的下一个地址 巷道
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-                   new RouteInfo("2532", new string[] { "TY1" }),
-                   new RouteInfo("2732", new string[] { "TY2" }),
-                   new RouteInfo("2527", new string[] { "TY1" }),
-                   new RouteInfo("2528", new string[] { "TY1" }),
-                   new RouteInfo("2727", new string[] { "TY2" }),
-                   new RouteInfo("2728", new string[] { "TY2" }),
-                   new RouteInfo("1603", new string[] { "TY1" }),
-            });
-
-            #endregion 堆垛机取货点的下一个地址 巷道
-
-            #endregion 入库路线
-
-            #region 满轮主线
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-
-                #region 分拣库一
-
-                //主线第一个扫码点--预分配点
+                //巷道--一楼堆垛机放货口
+                new RouteInfo("TY1", new string[] { "2532" }), //人工取货口
+                new RouteInfo("TY2", new string[] { "2732" }),
+                new RouteInfo("TY1", new string[] { "2534","2533" }),//AGV取货口
+                new RouteInfo("TY2", new string[] { "2734","2733" }),
+                //巷道--二楼堆垛机放货口
+                new RouteInfo("TY1", new string[] { "1601","1605" }),
+                new RouteInfo("TY2", new string[] { "1611","1615" }),
+                //二楼堆垛机放货口--二楼拆盘机
+                new RouteInfo("1601", new string[] { "1602" }),//非09拆盘机
+                new RouteInfo("1611", new string[] { "1612"}),
+                new RouteInfo("1605", new string[] { "1606" }),//09拆盘机
+                new RouteInfo("1615", new string[] { "1616" }),
+                //二楼拆盘机--RGV
+                new RouteInfo("1602", new string[] { "RGV1" }),//非09拆盘机
+                //new RouteInfo("1612", new string[] { "RGV2"}),
+                new RouteInfo("1606", new string[] { "RGV1" }),//09拆盘机
+                //new RouteInfo("1616", new string[] { "RGV2" }),
+                //RGV--码垛区域
+                new RouteInfo("RGV1", new string[] { "1661","1666" }),//北区机械臂码垛区
+                //new RouteInfo("RGV2", new string[] { }),//南区机械臂
+                new RouteInfo("RGV1", new string[] { "1662","1663","1664","1665", "1670","1671","1672","1673","1674","1675"}),//桁架北区码垛站台
+                //new RouteInfo("RGV2", new string[] { }),//南区桁架
+
+                #endregion 出库路径
+
+                #region 入库
+
+                //一楼人工入库口-巷道
+                new RouteInfo("2532", new string[] { "TY1" }),
+                new RouteInfo("2732", new string[] { "TY2" }),
+                //一楼叠盘机(堆垛机入口)--巷道
+                new RouteInfo("2527", new string[] { "TY1" }),
+                new RouteInfo("2528", new string[] { "TY1" }),
+                new RouteInfo("2727", new string[] { "TY2" }),
+                new RouteInfo("2728", new string[] { "TY2" }),
+                //一楼AGV入口
+                //主线入口--预分配点
                 new RouteInfo("1", new string[] { "18" }),
-                //预分配点--分流点
+                //预分配点--主线分流点
                 new RouteInfo("18", new string[] { "22" }),
-                //分流点--环形库分流点
+                //主线分流点--环形库分流点
                 new RouteInfo("22", new string[] { "418" }),
-
-                #endregion 分拣库一
-            });
-
-            #endregion 满轮主线
-
-            #region 满轮支线
-
-            routeInfos.AddRange(new List<RouteInfo>() {
-
-                #region 分拣库一
-
+                //环形库分流点--环形库取货点
+                new RouteInfo("418", new string[] { "424","433","442" }),
                 //环形库分流点--桁架分流点
                 new RouteInfo("418", new string[] { "455" }),
-                //桁架分流点--异常排出
-                new RouteInfo("455", new string[] { "591", }),
-                //桁架分流点--桁架取货线体缓存
-                new RouteInfo("455", new string[] { "466", "480", "494", "508", "522", "536" }),
-                //桁架取货线体缓存点--桁架取货点
+                //桁架分流点--桁架缓存放行点
+                new RouteInfo("455", new string[] { "466","480","494","508", "522","536","550","564","578"}),
+                //桁架分流点--异常缓存放行点
+                new RouteInfo("455", new string[] { "491" }),
+                //桁架缓存放行点--桁架取货点
                 new("466", new[] { "461" }),
                 new("480", new[] { "475" }),
                 new("494", new[] { "489" }),
                 new("508", new[] { "503" }),
                 new("522", new[] { "517" }),
                 new("536", new[] { "531" }),
-                //桁架取货点--码垛工位
-                new("461", new[] {"1670", "1671", "1672", "1673", "1674", "1675" }),
-                new("475", new[] { "1670", "1671", "1672", "1673", "1674", "1675" }),
-                new("489", new[] { "1670", "1671", "1672", "1673", "1674", "1675" }),
-                new("503", new[] { "1670", "1671", "1672", "1673", "1674", "1675" }),
-                new("517", new[] { "1670", "1671", "1672", "1673", "1674", "1675" }),
-                new("531", new[] { "1670", "1671", "1672", "1673", "1674", "1675" }),
-                //桁架码垛工位--RGV
-                new RouteInfo("1673", new string[] { "RGV1" }),
+                new("550", new[] { "545" }),
+                new("564", new[] { "559" }),
+                new("578", new[] { "573" }),
+                //桁架取货点--桁架
+                new("461", new[] { "Truss1" }),
+                new("475", new[] { "Truss1" }),
+                new("489", new[] { "Truss1" }),
+                new("503", new[] { "Truss1" }),
+                new("517", new[] { "Truss1" }),
+                new("531", new[] { "Truss1" }),
+                new("545", new[] { "Truss1" }),
+                new("559", new[] { "Truss1" }),
+                new("573", new[] { "Truss1" }),
+                //桁架--码垛工位
+                new("Truss1", new[] { "1662" }),
+                new("Truss1", new[] { "1663" }),
+                new("Truss1", new[] { "1664" }),
+                new("Truss1", new[] { "1665" }),
+                new("Truss1", new[] { "1670" }),
+                new("Truss1", new[] { "1671" }),
+                new("Truss1", new[] { "1672" }),
+                new("Truss1", new[] { "1673" }),
+                new("Truss1", new[] { "1674" }),
+                new("Truss1", new[] { "1675" }),
+                //码垛工位--RGV
+                new RouteInfo("1661", new string[] { "RGV1" }),//机械手码垛工位
+                new RouteInfo("1666", new string[] { "RGV1" }),
+                new RouteInfo("1662", new string[] { "RGV1" }),//绗架码垛工位
+                new RouteInfo("1663", new string[] { "RGV1" }),
+                new RouteInfo("1664", new string[] { "RGV1" }),
+                new RouteInfo("1665", new string[] { "RGV1" }),
+                new RouteInfo("1670", new string[] { "RGV1" }),
                 new RouteInfo("1671", new string[] { "RGV1" }),
                 new RouteInfo("1672", new string[] { "RGV1" }),
+                new RouteInfo("1673", new string[] { "RGV1" }),
                 new RouteInfo("1674", new string[] { "RGV1" }),
                 new RouteInfo("1675", new string[] { "RGV1" }),
-                //RGV--码垛工位
-                new RouteInfo("RGV1", new string[] { "1662", "1663", "1664", "1665","1604", "1661", "1675", "1674", "1673", "1672", "1671", "1670", "1669", "1668", "1667", "1666" }),
+                //RGV--RGV放货点
+                new RouteInfo("RGV1", new string[] { "1604" }),
+                //RGV放货点--堆垛机取货口
+                new RouteInfo("1604", new string[] { "1603" }),//北侧
 
-                #endregion 分拣库一
+                //二楼堆垛机入库--巷道
+                new RouteInfo("1603", new string[] { "TY1" }),//北侧
+                new RouteInfo("1613", new string[] { "TY2" }),//南侧
+
+                //巷道--堆垛机
+                new RouteInfo("TY1", new string[] { "SRM1" }),
+                new RouteInfo("TY2", new string[] { "SRM2" }),
+
+                #endregion 入库
             });
 
-            #endregion 满轮支线
+            #endregion 分拣库一
 
             foreach (var item in routeInfos)
             {
@@ -601,6 +565,8 @@ namespace WCS.WorkEngineering
                             _db.CodeFirst.InitTables(typeof(WCS_PalletizingLayer));
                             _db.CodeFirst.InitTables(typeof(WCS_PalletizingRow));
                             _db.CodeFirst.InitTables(typeof(WCS_PalletizingLoc));
+                            _db.CodeFirst.InitTables(typeof(WCS_CacheLine));
+                            _db.CodeFirst.InitTables(typeof(WCS_CacheLineLoc));
 
                             break;