Browse Source

堆垛机交互

林豪 左 2 years ago
parent
commit
039b307e0a
25 changed files with 526 additions and 62 deletions
  1. 1 1
      ServiceCenter/ServiceCenter.csproj
  2. 1 1
      WCS.Entity.Protocol/WCS.Entity.Protocol.csproj
  3. 8 2
      WCS.Entity/WCS_DeviceInfo.cs
  4. 2 2
      WCS.Entity/WCS_TaskInfo.cs
  5. 7 0
      WCS.Service/WCS.Service.csproj
  6. 2 1
      WCS.Service/Worker.cs
  7. 108 19
      WCS.WorkEngineering/Extensions/DeviceExtension.cs
  8. 22 0
      WCS.WorkEngineering/Extensions/SRMExtension.cs
  9. 12 0
      WCS.WorkEngineering/Extensions/StationExtension.cs
  10. 110 27
      WCS.WorkEngineering/Systems/SrmSystems.cs
  11. 1 1
      WCS.WorkEngineering/WCS.WorkEngineering.csproj
  12. 1 1
      WCS.WorkEngineering/WebApi/Controllers/AgvController.cs
  13. 41 0
      WCS.WorkEngineering/WebApi/Controllers/WmsApi.cs
  14. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/AgvCallbackRequest.cs
  15. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/CopperLineAgvTaskStockInToIWmsRequest.cs
  16. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/CopperLineAgvTaskStockOutToIWmsRequest.cs
  17. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/GenAgvSchedulingTaskRequest.cs
  18. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/GenAgvSchedulingTaskResponse.cs
  19. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/agvCallbackResponse.cs
  20. 51 0
      WCS.WorkEngineering/WebApi/Models/WMS/Request/I_WCS_GetWareCellRequest.cs
  21. 58 0
      WCS.WorkEngineering/WebApi/Models/WMS/Response/I_WCS_GetWareCellResponse.cs
  22. 11 0
      WCS.WorkEngineering/WebApi/Models/WMS/Response/WcsContractApiResponse.cs
  23. 25 0
      WCS.WorkEngineering/WorkConfigHub.cs
  24. 58 0
      WCS.WorkEngineering/Worlds/NoInteractionWorld.cs
  25. 1 1
      WCS.WorkEngineering/worlds/MainWorld.cs

+ 1 - 1
ServiceCenter/ServiceCenter.csproj

@@ -11,7 +11,7 @@
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
     <PackageReference Include="PlcSiemens" Version="1.0.0.2" />
     <PackageReference Include="PlcSiemens" Version="1.0.0.2" />
     <PackageReference Include="WCS.Core" Version="1.0.0.7" />
     <PackageReference Include="WCS.Core" Version="1.0.0.7" />
-    <PackageReference Include="WCS.Entity" Version="1.0.1.2" />
+    <PackageReference Include="WCS.Entity" Version="1.0.1.4" />
   </ItemGroup>
   </ItemGroup>
 
 
 </Project>
 </Project>

+ 1 - 1
WCS.Entity.Protocol/WCS.Entity.Protocol.csproj

@@ -7,7 +7,7 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="WCS.Entity" Version="1.0.1.2" />
+    <PackageReference Include="WCS.Entity" Version="1.0.1.4" />
   </ItemGroup>
   </ItemGroup>
 
 
 </Project>
 </Project>

+ 8 - 2
WCS.Entity/WCS_DeviceInfo.cs

@@ -31,10 +31,16 @@ namespace WCS.Entity
         public List<WCS_DeviceProt> DeviceProtocol { get; set; }
         public List<WCS_DeviceProt> DeviceProtocol { get; set; }
 
 
         /// <summary>
         /// <summary>
-        /// 设备可用路由集合
+        /// 上一个设备集合
+        /// </summary>
+        [Navigate(NavigateType.OneToMany, nameof(WCS_Route.NextCode))]
+        public List<WCS_Route> FormerRoutes { get; set; }
+
+        /// <summary>
+        /// 下一个设备集合
         /// </summary>
         /// </summary>
         [Navigate(NavigateType.OneToMany, nameof(WCS_Route.DeviceCode))]
         [Navigate(NavigateType.OneToMany, nameof(WCS_Route.DeviceCode))]
-        public List<WCS_Route> Routes { get; set; }
+        public List<WCS_Route> NextRoutes { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// 设备可用路径集合
         /// 设备可用路径集合

+ 2 - 2
WCS.Entity/WCS_TaskInfo.cs

@@ -276,7 +276,7 @@ namespace WCS.Entity
         /// 输送机执行中
         /// 输送机执行中
         /// </summary>
         /// </summary>
         [Description("输送机执行中")]
         [Description("输送机执行中")]
-        ConveyorInProgress = 10,
+        ConveyorExecution = 10,
 
 
         /// <summary>
         /// <summary>
         /// 堆垛机执行
         /// 堆垛机执行
@@ -294,7 +294,7 @@ namespace WCS.Entity
         /// AGV执行中
         /// AGV执行中
         /// </summary>
         /// </summary>
         [Description("AGV执行中")]
         [Description("AGV执行中")]
-        AGVInProgress = 40,
+        AGVExecution = 40,
 
 
         /// <summary>
         /// <summary>
         /// 已完成
         /// 已完成

+ 7 - 0
WCS.Service/WCS.Service.csproj

@@ -7,6 +7,13 @@
     <UserSecretsId>dotnet-WCS.Service-ee485c84-3250-46d0-8109-1d37d3b27230</UserSecretsId>
     <UserSecretsId>dotnet-WCS.Service-ee485c84-3250-46d0-8109-1d37d3b27230</UserSecretsId>
   </PropertyGroup>
   </PropertyGroup>
 
 
+  <ItemGroup>
+    <Compile Remove="Logs\**" />
+    <Content Remove="Logs\**" />
+    <EmbeddedResource Remove="Logs\**" />
+    <None Remove="Logs\**" />
+  </ItemGroup>
+
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="MessagePack" Version="2.5.108" />
     <PackageReference Include="MessagePack" Version="2.5.108" />
     <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
     <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />

+ 2 - 1
WCS.Service/Worker.cs

@@ -142,7 +142,8 @@ namespace WCS.Service
             SqlSugarHelper.Do(db =>
             SqlSugarHelper.Do(db =>
             {
             {
                 ServiceHub.deviceInfos = db.Default.Queryable<WCS_DeviceInfo>()
                 ServiceHub.deviceInfos = db.Default.Queryable<WCS_DeviceInfo>()
-                                                   .Includes(v => v.Routes)
+                                                   .Includes(v => v.NextRoutes)
+                                                   .Includes(v => v.FormerRoutes)
                                                    .Includes(v => v.Paths)
                                                    .Includes(v => v.Paths)
                                                    .Includes(v => v.DeviceGroup)
                                                    .Includes(v => v.DeviceGroup)
                                                    .Includes(v => v.DeviceProtocol)
                                                    .Includes(v => v.DeviceProtocol)

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

@@ -1,5 +1,6 @@
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using WCS.Core;
 using WCS.Core;
+using WCS.Entity;
 using WCS.Entity.Protocol.Station;
 using WCS.Entity.Protocol.Station;
 
 
 namespace WCS.WorkEngineering.Extensions
 namespace WCS.WorkEngineering.Extensions
@@ -9,15 +10,61 @@ namespace WCS.WorkEngineering.Extensions
     /// </summary>
     /// </summary>
     public static class DeviceExtension
     public static class DeviceExtension
     {
     {
+        /// <summary>
+        ///  是否是输送线
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns></returns>
         public static bool IsConv(this Device source)
         public static bool IsConv(this Device source)
         {
         {
             return source.HasProtocol(typeof(IStation521)) || source.HasProtocol(typeof(IStation520)) || source.HasProtocol(typeof(IStation523));
             return source.HasProtocol(typeof(IStation521)) || source.HasProtocol(typeof(IStation520)) || source.HasProtocol(typeof(IStation523));
         }
         }
 
 
+        /// <summary>
+        ///  是否是巷道
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns></returns>
+        public static bool IsTunnel(this WCS_DeviceInfo source)
+        {
+            return source.Code.Contains("TY");
+        }
+
+        /// <summary>
+        ///  获取下一个地址
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <param name="addto">目标地址</param>
+        /// <returns></returns>
+        public static string GetNextAdd(this WCS_DeviceInfo source, string addto)
+        {
+            var path = source.Paths.First(p => p.EndCode == addto).Path;
+            return path.Split('-')[0];
+        }
+
+        /// <summary>
+        ///  获取到达目标地址需要的路径信息
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <param name="addto">目标地址</param>
+        /// <returns></returns>
+        public static string GetAddtoPath(this WCS_DeviceInfo source, string addto)
+        {
+            return source.Paths.First(p => p.EndCode == addto).Path;
+        }
+
         #region WCS_DEVICE扩展数据
         #region WCS_DEVICE扩展数据
 
 
+        /// <summary>
+        ///  设备标识字典
+        /// </summary>
         private static ConcurrentDictionary<string, object> DeviceValues = new ConcurrentDictionary<string, object>();
         private static ConcurrentDictionary<string, object> DeviceValues = new ConcurrentDictionary<string, object>();
 
 
+        /// <summary>
+        /// 添加设备标识
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <param name="flag">标识</param>
         public static void AddFlag(this Device source, DF flag)
         public static void AddFlag(this Device source, DF flag)
         {
         {
             var df = source.Get<DF>("DeviceFlag");
             var df = source.Get<DF>("DeviceFlag");
@@ -25,17 +72,37 @@ namespace WCS.WorkEngineering.Extensions
             source.Set("DeviceFlag", df);
             source.Set("DeviceFlag", df);
         }
         }
 
 
+        /// <summary>
+        ///  当前设备是否包含标识
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <param name="flag">标识</param>
+        /// <returns></returns>
         public static bool Is(this Device source, DF flag)
         public static bool Is(this Device source, DF flag)
         {
         {
             var df = source.Get<DF>("DeviceFlag");
             var df = source.Get<DF>("DeviceFlag");
             return (df & flag) == flag;
             return (df & flag) == flag;
         }
         }
 
 
+        /// <summary>
+        ///  为设备写入标识
+        /// </summary>
+        /// <typeparam name="T">写入值类型</typeparam>
+        /// <param name="source">设备信息</param>
+        /// <param name="key">标识类型</param>
+        /// <param name="value">写入值</param>
         public static void Set<T>(this Device source, string key, T value)
         public static void Set<T>(this Device source, string key, T value)
         {
         {
             DeviceValues[source.Code + key] = value;
             DeviceValues[source.Code + key] = value;
         }
         }
 
 
+        /// <summary>
+        ///  获取设备标识
+        /// </summary>
+        /// <typeparam name="T">写入值类型</typeparam>
+        /// <param name="source">设备信息</param>
+        /// <param name="key">标识类型</param>
+        /// <returns></returns>
         public static T Get<T>(this Device source, string key)
         public static T Get<T>(this Device source, string key)
         {
         {
             if (!DeviceValues.ContainsKey(source.Code + key))
             if (!DeviceValues.ContainsKey(source.Code + key))
@@ -43,36 +110,75 @@ namespace WCS.WorkEngineering.Extensions
             return (T)DeviceValues[source.Code + key];
             return (T)DeviceValues[source.Code + key];
         }
         }
 
 
+        /// <summary>
+        ///  获取short类型的设备号
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns></returns>
         public static short Code(this Device source)
         public static short Code(this Device source)
         {
         {
             return short.Parse(source.Code);
             return short.Parse(source.Code);
         }
         }
 
 
+        /// <summary>
+        ///  获取巷道
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns>返回巷道Code</returns>
         public static string Tunnel(this Device source)
         public static string Tunnel(this Device source)
         {
         {
             return source.Get<string>("Tunnel");
             return source.Get<string>("Tunnel");
         }
         }
 
 
+        /// <summary>
+        ///  获取巷道号
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns>返回巷道号</returns>
         public static int TunnelNum(this Device source)
         public static int TunnelNum(this Device source)
         {
         {
             return int.Parse(source.Tunnel().Last().ToString());
             return int.Parse(source.Tunnel().Last().ToString());
         }
         }
 
 
+        /// <summary>
+        ///  获取设备楼层信息
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns></returns>
         public static int Floor(this Device source)
         public static int Floor(this Device source)
         {
         {
             return source.Get<int>("Floor");
             return source.Get<int>("Floor");
         }
         }
 
 
-        public static Device SC(this Device source)
+        /// <summary>
+        ///  获取堆垛机
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns></returns>
+        public static Device SRM(this Device source)
         {
         {
-            return source.Get<Device>("SC");
+            return source.Get<Device>("SRM");
         }
         }
 
 
+        /// <summary>
+        ///  获取RGV
+        /// </summary>
+        /// <param name="source">设备信息</param>
+        /// <returns></returns>
         public static Device RGV(this Device source)
         public static Device RGV(this Device source)
         {
         {
             return source.Get<Device>("RGV");
             return source.Get<Device>("RGV");
         }
         }
 
 
+        //public static void AddFlag(DF flag, params string[] devices)
+        //{
+        //    var arr = LogicHandler.AllObjects.OfType<WCS_DEVICE>().Where(v => devices.Contains(v.CODE)).ToArray();
+        //    Parallel.ForEach(arr, v =>
+        //    {
+        //        v.AddFlag(flag);
+        //    });
+        //}
+
         #endregion WCS_DEVICE扩展数据
         #endregion WCS_DEVICE扩展数据
     }
     }
 
 
@@ -83,22 +189,5 @@ namespace WCS.WorkEngineering.Extensions
     public enum DF
     public enum DF
     {
     {
         无 = 0,
         无 = 0,
-        SRM = 1 << 0,
-        SRM二级品取货 = 1 << 1,
-        SRM涂布取货 = 1 << 2,
-        SRM月台放货 = 1 << 3,
-        一楼RGV放货 = 1 << 4,
-        月台 = 1 << 5,
-        涂布RGV = 1 << 6,
-        BOPPRGV = 1 << 7,
-        涂布RGV取货设备组 = 1 << 8,
-        涂布RGV放货设备组 = 1 << 9,
-        涂布出库RGV取货站台 = 1 << 10,
-        涂布入库RGV取货站台 = 1 << 11,
-        SRM涂布放货 = 1 << 12,
-        涂布RGV取货站台 = 1 << 13,
-        BOPPRGV取货设备组 = 1 << 14,
-        BOPPRGV放货设备组 = 1 << 15,
-        SRMBOPP取货 = 1 << 16,
     }
     }
 }
 }

+ 22 - 0
WCS.WorkEngineering/Extensions/SRMExtension.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WCS.Core;
+using WCS.Entity.Protocol.SRM;
+
+namespace WCS.WorkEngineering.Extensions
+{
+    /// <summary>
+    /// 堆垛机扩展
+    /// </summary>
+    public class SRM : Device<ISRM520, ISRM521, ISRM523>
+    {
+        public SRM(Device device) : base(device)
+        {
+        }
+    }
+
+
+}

+ 12 - 0
WCS.WorkEngineering/Extensions/StationExtension.cs

@@ -0,0 +1,12 @@
+using WCS.Core;
+using WCS.Entity.Protocol.Station;
+
+namespace WCS.WorkEngineering.Extensions
+{
+    public class Station : Device<IStation520, IStation521, IStation523>
+    {
+        public Station(Device device) : base(device)
+        {
+        }
+    }
+}

+ 110 - 27
WCS.WorkEngineering/Systems/SrmSystems.cs

@@ -1,4 +1,5 @@
-using ServiceCenter.Extensions;
+using ServiceCenter;
+using ServiceCenter.Extensions;
 using ServiceCenter.SqlSugars;
 using ServiceCenter.SqlSugars;
 using System.ComponentModel;
 using System.ComponentModel;
 using WCS.Core;
 using WCS.Core;
@@ -6,9 +7,11 @@ using WCS.Entity;
 using WCS.Entity.Protocol.SRM;
 using WCS.Entity.Protocol.SRM;
 using WCS.Entity.Protocol.Station;
 using WCS.Entity.Protocol.Station;
 using WCS.WorkEngineering.Extensions;
 using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.WebApi.Controllers;
 using WCS.WorkEngineering.Worlds;
 using WCS.WorkEngineering.Worlds;
 using WCS.WorkEngineering.Worlds.Logs;
 using WCS.WorkEngineering.Worlds.Logs;
 using KnownException = WCS.WorkEngineering.Worlds.Logs.KnownException;
 using KnownException = WCS.WorkEngineering.Worlds.Logs.KnownException;
+using TaskStatus = WCS.Entity.TaskStatus;
 
 
 namespace WCS.WorkEngineering.Systems
 namespace WCS.WorkEngineering.Systems
 {
 {
@@ -17,42 +20,40 @@ namespace WCS.WorkEngineering.Systems
     /// </summary>
     /// </summary>
     [BelongTo(typeof(MainWorld))]
     [BelongTo(typeof(MainWorld))]
     [Description("堆垛机系统")]
     [Description("堆垛机系统")]
-    public class SrmSystems : DeviceSystem<Device<ISRM520, ISRM521, ISRM523>>
+    public class SrmSystems : DeviceSystem<SRM>
     {
     {
         /// <summary>
         /// <summary>
         /// 取货点设备集合
         /// 取货点设备集合
         /// </summary>
         /// </summary>
-        private List<Device<IStation520, IStation521, IStation523>> PickUpDevices;
+        private Dictionary<string, List<Station>> PickUpDevices = new Dictionary<string, List<Station>>();
 
 
         /// <summary>
         /// <summary>
         /// 放货设备
         /// 放货设备
         /// </summary>
         /// </summary>
-        private List<Device<IStation520, IStation521, IStation523>> PutDevices;
+        private Dictionary<string, List<Station>> PutDevices = new Dictionary<string, List<Station>>();
 
 
         public SrmSystems()
         public SrmSystems()
         {
         {
-            //分拣库1
-            PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
-                                         .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
-            PutDevices = World.Devices.Where(v => v.Code is "" or "")
-                                         .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
-            //分拣库2
-            PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
-                                         .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
-            PutDevices = World.Devices.Where(v => v.Code is "" or "")
-                                         .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
-            //分拣库3
-            PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
-                                         .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
-            PutDevices = World.Devices.Where(v => v.Code is "" or "")
-                                         .Select(v => new Device<IStation520, IStation521, IStation523>(v)).ToList();
+            //获取所有的巷道集合
+            var devices = ServiceHub.deviceInfos.Where(x => x.IsTunnel());
+
+            //开始分配
+            foreach (var item in devices)
+            {
+                //取货设备
+                var deviceCode = item.FormerRoutes.Select(v => v.DeviceCode).ToList();
+                PickUpDevices.Add(item.NextRoutes.First().DeviceCode, World.Devices.Where(v => deviceCode.Contains(v.Code)).Select(v => new Station(v)).ToList());
+                //放货设备
+                deviceCode = ServiceHub.deviceInfos.First(x => item.NextRoutes.First().DeviceCode == x.Code).NextRoutes.Select(v => v.NextCode).ToList();
+                PutDevices.Add(item.NextRoutes.First().DeviceCode, World.Devices.Where(v => deviceCode.Contains(v.Code)).Select(v => new Station(v)).ToList());
+            }
         }
         }
 
 
         protected override bool ParallelDo => true;
         protected override bool ParallelDo => true;
 
 
         protected override bool SaveLogsToFile => true;
         protected override bool SaveLogsToFile => true;
 
 
-        public override void Do(Device<ISRM520, ISRM521, ISRM523> obj)
+        public override void Do(SRM obj)
         {
         {
             //判断堆垛机是否报警
             //判断堆垛机是否报警
             if (obj.Data2.Status.HasFlag(SrmStatus.Alarm)) throw new KnownException(obj.Data3.Alarm.ToString(), LogLevelEnum.High);
             if (obj.Data2.Status.HasFlag(SrmStatus.Alarm)) throw new KnownException(obj.Data3.Alarm.ToString(), LogLevelEnum.High);
@@ -80,7 +81,7 @@ namespace WCS.WorkEngineering.Systems
                               break;
                               break;
 
 
                           case TaskType.OutDepot:
                           case TaskType.OutDepot:
-                              task.Status = Entity.TaskStatus.ConveyorInProgress;
+                              task.Status = Entity.TaskStatus.ConveyorExecution;
                               task.AddWCS_TASK_DTL(db, task.SrmStation, "出库任务到达放货站台");
                               task.AddWCS_TASK_DTL(db, task.SrmStation, "出库任务到达放货站台");
                               break;
                               break;
 
 
@@ -129,9 +130,8 @@ namespace WCS.WorkEngineering.Systems
                 {
                 {
                     //获取出库任务中新建状态最大优先级
                     //获取出库任务中新建状态最大优先级
                     var outPriorityNewBuild = tasks.Where(v => v.Type == TaskType.OutDepot && v.Status == Entity.TaskStatus.NewBuild).Max(v => v.Priority);
                     var outPriorityNewBuild = tasks.Where(v => v.Type == TaskType.OutDepot && v.Status == Entity.TaskStatus.NewBuild).Max(v => v.Priority);
-                    //获取入库任务中最后一个交互点是取货点任务的最大优先级
-                    var enterPriority = tasks.Where(v => v.Type == TaskType.EnterDepot && v.Status < Entity.TaskStatus.StackerExecution && PickUpDevices.Any(p => p.Entity.Code == v.LastInteractionPoint))
-                                             .Max(v => v.Priority);
+                    //获取入库任务中最大优先级
+                    var enterPriority = tasks.Where(v => v.Type == TaskType.EnterDepot && v.Status < Entity.TaskStatus.StackerExecution).Max(v => v.Priority);
                     //出入库最大优先级相加大于零
                     //出入库最大优先级相加大于零
                     if (outPriorityNewBuild + enterPriority > 0)
                     if (outPriorityNewBuild + enterPriority > 0)
                     {
                     {
@@ -186,14 +186,97 @@ namespace WCS.WorkEngineering.Systems
             if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
             if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
             {
             {
                 //判断本次优先执行楼层,并设置下次执行时优先楼层
                 //判断本次优先执行楼层,并设置下次执行时优先楼层
-                var floor = obj.Entity.Get<int>("Floor");
+                var floor = obj.Entity.Get<int>("FloorIn");
                 floor = floor % 2 + 1;
                 floor = floor % 2 + 1;
-                obj.Entity.Set("Floor", floor);
-                
+                obj.Entity.Set("FloorIn", floor);
+
                 //获取当前堆垛机所有的取货站台
                 //获取当前堆垛机所有的取货站台
+                var arrIn = PickUpDevices.First(v => v.Key == obj.Entity.Code).Value;
+                if (!arrIn.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无取货路径点", LogLevelEnum.High);
+
+                //获取有货的设备
+                arrIn = arrIn.Where(v => v.Data2.TaskNumber > 0 && v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList();
+                if (!arrIn.Any()) throw new KnownException($"[{obj.Entity.Code}]等待入库任务输送到位", LogLevelEnum.Mid);
+                WCS_TaskInfo taskInfo = null;
+                Station station = null;
+                var result = SqlSugarHelper.Do(db =>
+                {
+                    //根据有货设备的任务号获取所有类型为入库状态为输送机执行中的任务
+                    var tasks = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.EnterDepot && v.Status == TaskStatus.ConveyorExecution && arrIn.Select(p => p.Data2.TaskNumber).Contains(v.ID));
+                    //按条件先后排序获取一条排序后第一条结果1.优先级2.所在楼层与本次优先执行楼层 TODO:待验证排序结果
+                    var task = tasks.OrderByDescending(v => v.Priority).OrderByDescending(v => v.Floor == floor ? 1 : 0).First() ?? throw new KnownException($"{obj.Entity.Code}未找到入库任务", LogLevelEnum.High);
+                    //获取任务所有设备
+                    station = arrIn.First(v => v.Data2.TaskNumber == task.ID);
+                    //获取当前货物巷道
+                    var loc = WmsApi.GetLocalIn(task.ID, task.Tunnel, station.Entity.Code);
+
+                    task.Status = TaskStatus.StackerExecution;
+                    task.AddrTo = $"{loc.Row}-{loc.Colomn}-{loc.Layer}";
+                    task.LastInteractionPoint = station.Entity.Code;
+                    task.EditWho = "WCS";
+                    task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行");
+                    db.Default.Updateable(task).AddQueue();
+                    db.Default.SaveQueues();
+                });
+
+                if (taskInfo == null || !result) throw new KnownException("数据更新错误", LogLevelEnum.High);
+                var addrTo = taskInfo.AddrTo.Split("-");
+                //下发任务
+                obj.Data.TaskNumber = taskInfo.ID;
+                obj.Data.RowPos1 = station.Entity.Code.ToShort();
+                obj.Data.RowPos2 = addrTo[0].ToShort();
+                obj.Data.TravelPos2 = addrTo[1].ToShort();
+                obj.Data.LiftPos2 = addrTo[2].ToShort();
+                obj.Data.VoucherNo++;
             }
             }
             else if (enterOrOut == 3 || !lastIsOut) //出库任务
             else if (enterOrOut == 3 || !lastIsOut) //出库任务
             {
             {
+                //判断本次优先执行楼层,并设置下次执行时优先楼层
+                var floor = obj.Entity.Get<int>("FloorOut");
+                floor = floor % 2 + 1;
+                obj.Entity.Set("FloorOut", floor);
+
+                //获取当前堆垛机所有的取货站台
+                var arrOut = PickUpDevices.First(v => v.Key == obj.Entity.Code).Value;
+                if (!arrOut.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无放货路径点", LogLevelEnum.High);
+
+                //获取可以放货的设备集合
+                arrOut = arrOut.Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) //无光电
+                                        && !v.Data3.Status.HasFlag(StatusEunm.Run) //未运行
+                                        && !v.Data3.Status.HasFlag(StatusEunm.OT_Status) //无任务
+                                        && !v.Data3.Status.HasFlag(StatusEunm.UnassignedTask) //未分配任务
+                                        && v.Data3.Status.HasFlag(StatusEunm.Auto)).ToList(); //自动
+                if (!arrOut.Any()) throw new KnownException($"[{obj.Entity.Code}]等待出库任务输送到位", LogLevelEnum.Mid);
+                WCS_TaskInfo taskInfo = null;
+                string[] addrFrom = null;
+
+                var result = SqlSugarHelper.Do(db =>
+                {
+                    var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();
+                    //按条件先后排序获取一条排序后第一条结果1.优先级2.所在楼层与本次优先执行楼层 TODO:待验证排序结果
+                    var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.WaitingToExecute)
+                                                                   .Where(v => allOutCode.Contains(v.SrmStation))
+                                                                   .OrderByDescending(v => v.Priority)
+                                                                   .OrderByDescending(v => v.Floor == floor ? 1 : 0)
+                                                                   .First() ?? throw new KnownException($"{obj.Entity.Code}未找到出库任务", LogLevelEnum.High);
+
+                    addrFrom = task.AddrFrom.Split("-");
+                    task.Status = TaskStatus.StackerExecution;
+                    task.LastInteractionPoint = task.Device;
+                    task.EditWho = "WCS";
+                    task.AddWCS_TASK_DTL(db, task.Device, task.SrmStation, "任务下发堆垛机执行");
+                    db.Default.Updateable(task).AddQueue();
+                    taskInfo = task;
+                    db.Default.SaveQueues();
+                });
+
+                obj.Data.TaskNumber = taskInfo.ID;
+                obj.Data.RowPos1 = addrFrom[0].ToShort();
+                obj.Data.TravelPos1 = addrFrom[1].ToShort();
+                obj.Data.LiftPos1 = addrFrom[2].ToShort();
+                obj.Data.RowPos2 = taskInfo.SrmStation.ToShort();
+                obj.Data.TravelPos2 = taskInfo.AddrNext.ToShort();
+                obj.Data.VoucherNo++;
             }
             }
 
 
             #endregion 出入库
             #endregion 出入库

+ 1 - 1
WCS.WorkEngineering/WCS.WorkEngineering.csproj

@@ -8,7 +8,7 @@
 
 
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
-    <PackageReference Include="ServiceCenter" Version="1.0.1.6" />
+    <PackageReference Include="ServiceCenter" Version="1.0.1.8" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 1 - 1
WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -1,5 +1,5 @@
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
-using WCS.WorkEngineering.WebApi.Models;
+using WCS.WorkEngineering.WebApi.Models.AGV;
 
 
 namespace WCS.WorkEngineering.WebApi.Controllers
 namespace WCS.WorkEngineering.WebApi.Controllers
 {
 {

+ 41 - 0
WCS.WorkEngineering/WebApi/Controllers/WmsApi.cs

@@ -0,0 +1,41 @@
+using ServiceCenter.WebApi;
+using WCS.WorkEngineering.WebApi.Models.WMS.Request;
+using WCS.WorkEngineering.WebApi.Models.WMS.Response;
+using WCS.WorkEngineering.Worlds.Logs;
+
+namespace WCS.WorkEngineering.WebApi.Controllers
+{
+    /// <summary>
+    /// AGV相关接口控制器
+    /// </summary>
+
+    public static class WmsApi
+    {
+        private static string Url = "http://192.168.249.150:8026";
+
+        private static string wareHouseId = "opphouse";
+
+        /// <summary>
+        /// 分配货位
+        /// </summary>
+        /// <param name="wcsTaskNum">WMS任务ID</param>
+        /// <param name="tunnel">巷道</param>
+        /// <param name="device">设备号</param>
+        /// <returns></returns>
+        /// <exception cref="Exception"></exception>
+        public static I_WCS_GetWareCellResponse GetLocalIn(int wcsTaskNum, string tunnel, string device)
+        {
+            var res = APICaller.CallApi2<I_WCS_GetWareCellResponse>(Url + "/api/Task/I_WCS_GetWareCell", new I_WCS_GetWareCellRequest
+            {
+                PickUpEquipmentNo = device,
+                TunnelNum = tunnel.Last().ToString(),
+                WCSTaskNum = wcsTaskNum.ToString(),
+            });
+            if (!res.ResType)
+            {
+                throw new KnownException(res.ResMessage, LogLevelEnum.High);
+            }
+            return res;
+        }
+    }
+}

+ 1 - 1
WCS.WorkEngineering/WebApi/Models/AgvCallbackRequest.cs → WCS.WorkEngineering/WebApi/Models/AGV/AgvCallbackRequest.cs

@@ -1,4 +1,4 @@
-namespace WCS.WorkEngineering.WebApi.Models
+namespace WCS.WorkEngineering.WebApi.Models.AGV
 {
 {
     public class AgvCallbackRequest
     public class AgvCallbackRequest
     {
     {

+ 1 - 1
WCS.WorkEngineering/WebApi/Models/CopperLineAgvTaskStockInToIWmsRequest.cs → WCS.WorkEngineering/WebApi/Models/AGV/CopperLineAgvTaskStockInToIWmsRequest.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 
 
-namespace WCS.WorkEngineering.WebApi.Models
+namespace WCS.WorkEngineering.WebApi.Models.AGV
 {
 {
     public class CopperLineAgvTaskStockInToIWmsRequest
     public class CopperLineAgvTaskStockInToIWmsRequest
     {
     {

+ 1 - 1
WCS.WorkEngineering/WebApi/Models/CopperLineAgvTaskStockOutToIWmsRequest.cs → WCS.WorkEngineering/WebApi/Models/AGV/CopperLineAgvTaskStockOutToIWmsRequest.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 
 
-namespace WCS.WorkEngineering.WebApi.Models
+namespace WCS.WorkEngineering.WebApi.Models.AGV
 {
 {
     public class CopperLineAgvTaskStockOutToIWmsRequest
     public class CopperLineAgvTaskStockOutToIWmsRequest
     {
     {

+ 1 - 1
WCS.WorkEngineering/WebApi/Models/GenAgvSchedulingTaskRequest.cs → WCS.WorkEngineering/WebApi/Models/AGV/GenAgvSchedulingTaskRequest.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 
 
-namespace WCS.WorkEngineering.WebApi.Models
+namespace WCS.WorkEngineering.WebApi.Models.AGV
 {
 {
     public class GenAgvSchedulingTaskRequest
     public class GenAgvSchedulingTaskRequest
     {
     {

+ 1 - 1
WCS.WorkEngineering/WebApi/Models/GenAgvSchedulingTaskResponse.cs → WCS.WorkEngineering/WebApi/Models/AGV/GenAgvSchedulingTaskResponse.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 
 
-namespace WCS.WorkEngineering.WebApi.Models
+namespace WCS.WorkEngineering.WebApi.Models.AGV
 {
 {
     public class GenAgvSchedulingTaskResponse
     public class GenAgvSchedulingTaskResponse
     {
     {

+ 1 - 1
WCS.WorkEngineering/WebApi/Models/agvCallbackResponse.cs → WCS.WorkEngineering/WebApi/Models/AGV/agvCallbackResponse.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 
 
-namespace WCS.WorkEngineering.WebApi.Models
+namespace WCS.WorkEngineering.WebApi.Models.AGV
 {
 {
     public class AgvCallbackResponse
     public class AgvCallbackResponse
     {
     {

+ 51 - 0
WCS.WorkEngineering/WebApi/Models/WMS/Request/I_WCS_GetWareCellRequest.cs

@@ -0,0 +1,51 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace WCS.WorkEngineering.WebApi.Models.WMS.Request
+{
+    /// <summary>
+    /// 分配货位请求实体
+    /// </summary>
+    public class I_WCS_GetWareCellRequest
+    {
+        /// <summary>
+        /// WCS任务号
+        /// </summary>
+        [Required(ErrorMessage = "{0} 不可为空")]
+        public string WCSTaskNum { get; set; }
+
+        /// <summary>
+        /// 巷道号
+        /// </summary>
+        public string TunnelNum { get; set; }
+
+        /// <summary>
+        /// 取货地点设备编号
+        /// </summary>
+        [Required(ErrorMessage = "{0} 不可为空")]
+        public string PickUpEquipmentNo { get; set; }
+
+        /// <summary>
+        /// 货叉(1,货叉1(左);2,货叉2(右))
+        /// </summary>
+        public WareCellForkNum ForkNum { get; set; }
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        public string Memo1 { get; set; }
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        public string Memo2 { get; set; }
+    }
+
+    /// <summary>
+    /// 申请货位任务对应的货叉
+    /// </summary>
+    public enum WareCellForkNum : int
+    {
+        货叉1 = 1,
+        货叉2 = 2,
+    }
+}

+ 58 - 0
WCS.WorkEngineering/WebApi/Models/WMS/Response/I_WCS_GetWareCellResponse.cs

@@ -0,0 +1,58 @@
+namespace WCS.WorkEngineering.WebApi.Models.WMS.Response
+{
+    /// <summary>
+    /// 分配货位响应实体
+    /// </summary>
+    public class I_WCS_GetWareCellResponse : WcsContractApiResponse
+    {
+        /// <summary>
+        /// 结果
+        /// </summary>
+        public bool ResType { get; set; }
+
+        /// <summary>
+        /// 消息
+        /// </summary>
+        public string ResMessage { get; set; }
+
+        /// <summary>
+        /// 货位号
+        /// </summary>
+        public string CellNo { get; set; }
+
+        /// <summary>
+        /// 巷道号
+        /// </summary>
+        public string TunnelNum { get; set; }
+
+        /// <summary>
+        /// 行
+        /// </summary>
+        public short Row { get; set; }
+
+        /// <summary>
+        /// 列
+        /// </summary>
+        public short Colomn { get; set; }
+
+        /// <summary>
+        /// 层
+        /// </summary>
+        public short Layer { get; set; }
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        public string Memo1 { get; set; }
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        public string Memo2 { get; set; }
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        public string Memo3 { get; set; }
+    }
+}

+ 11 - 0
WCS.WorkEngineering/WebApi/Models/WMS/Response/WcsContractApiResponse.cs

@@ -0,0 +1,11 @@
+namespace WCS.WorkEngineering.WebApi.Models.WMS.Response
+{
+    public class WcsContractApiResponse
+    {
+        public bool ResType { get; set; }
+        public string ResMessage { get; set; }
+        public string Memo1 { get; set; }
+        public string Memo2 { get; set; }
+        public string Memo3 { get; set; }
+    }
+}

+ 25 - 0
WCS.WorkEngineering/WorkConfigHub.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WCS.Core;
+using WCS.WorkEngineering.Extensions;
+
+namespace WCS.WorkEngineering
+{
+    /// <summary>
+    /// 业务工程配置信息
+    /// </summary>
+    public static  class WorkConfigHub
+    {
+        /// <summary>
+        ///  初始化设备标识配置信息
+        /// </summary>
+
+        public static void InitDeviceFlag() 
+        {
+            //DeviceExtension.AddFlag();
+        }
+    }
+}

+ 58 - 0
WCS.WorkEngineering/Worlds/NoInteractionWorld.cs

@@ -0,0 +1,58 @@
+using ServiceCenter;
+using ServiceCenter.SqlSugars;
+using System.ComponentModel;
+using WCS.Entity;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Worlds.Logs;
+
+namespace WCS.WorkEngineering.Worlds
+{
+    /// <summary>
+    /// 非交互世界
+    /// </summary>
+    [Description("非交互世界")]
+    public class NoInteractionWorld : MainWorld
+    {
+        /// <summary>
+        ///  世界执行周期间隔
+        ///  单位:毫秒
+        /// </summary>
+        protected override int Interval => 300;
+
+        /// <summary>
+        ///  更新前执行,重写改方法后请自行添加执行内容
+        ///  执行内容:清空日志队列
+        /// </summary>
+        protected override void BeforeUpdate()
+        {
+            // 清空日志队列,确保日志队列中只会有当前周期日志
+            Logs.Clear();
+
+            #region 处理所有新建出库任务
+
+            SqlSugarHelper.Do(db =>
+            {
+                //获取所有新建状态的出库任务
+                var tasks = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.Status == Entity.TaskStatus.NewBuild).ToList();
+                if (tasks.Count > 0)
+                {
+                    Log(new LogInfo { Level = LogLevelEnum.Low, Type = ErrorTypeEnum.Kown, LogUpLoad = LogUpLoadEnum.NotUpLoad, Message = "无新建出库任务" });
+                }
+                tasks.ForEach(task =>
+                {
+                    //获取堆垛机到目标地址的路径信息
+                    var path = ServiceHub.deviceInfos.First(v => v.Code == task.Device).Paths.First(v => v.EndCode == task.AddrTo).Path.Split("-");
+                    //
+                    task.SrmStation = path[1];
+                    task.AddrNext = path[2];
+                    task.Status = Entity.TaskStatus.WaitingToExecute;
+                    task.AddWCS_TASK_DTL(db, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}、放货后下一个地址:{task.AddrNext}");
+                    db.Default.Updateable(task).AddQueue();
+                });
+                db.Default.SaveQueues();
+            });
+
+            #endregion 处理所有新建出库任务
+        }
+    }
+}

+ 1 - 1
WCS.WorkEngineering/worlds/MainWorld.cs

@@ -25,7 +25,7 @@ namespace WCS.WorkEngineering.Worlds
         /// <summary>
         /// <summary>
         ///  日志队列
         ///  日志队列
         /// </summary>
         /// </summary>
-        private ConcurrentQueue<KeyLog> Logs = new ConcurrentQueue<KeyLog>();
+        protected ConcurrentQueue<KeyLog> Logs = new ConcurrentQueue<KeyLog>();
 
 
         /// <summary>
         /// <summary>
         ///  世界执行周期间隔
         ///  世界执行周期间隔