林豪 左 2 anos atrás
pai
commit
98c4c3679c
32 arquivos alterados com 781 adições e 212 exclusões
  1. 18 18
      ServiceCenter/Extensions/LinqExtension.cs
  2. 5 3
      ServiceCenter/ServiceCenter.csproj
  3. 79 89
      WCS.Core/World.cs
  4. 7 5
      WCS.Entity.Protocol/SRM/SrmEnum.cs
  5. 1 1
      WCS.Entity.Protocol/Station/IStation520.cs
  6. 6 0
      WCS.Entity/WCS_TaskInfo.cs
  7. 8 4
      WCS.Service/PLCAccessors/PLCAccessorsCreater.cs
  8. 7 18
      WCS.Service/Worker.cs
  9. 29 0
      WCS.Service/Worlds/initWorld.cs
  10. 3 0
      WCS.WorkEngineering/Extensions/DeviceExtension.cs
  11. 2 1
      WCS.WorkEngineering/Systems/AgvSystems.cs
  12. 127 0
      WCS.WorkEngineering/Systems/DeviceWriteSystem.cs
  13. 64 0
      WCS.WorkEngineering/Systems/InboundSiteInteractionSystem.cs
  14. 4 1
      WCS.WorkEngineering/Systems/OutboundSiteInteractionSystems.cs
  15. 8 2
      WCS.WorkEngineering/Systems/SrmSystems.cs
  16. 0 48
      WCS.WorkEngineering/Systems/StorageSysyem.cs
  17. 6 1
      WCS.WorkEngineering/WCS.WorkEngineering.csproj
  18. 58 0
      WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs
  19. 3 2
      WCS.WorkEngineering/WebApi/Controllers/AgvController.cs
  20. 51 0
      WCS.WorkEngineering/WebApi/Controllers/WcsController.cs
  21. 28 0
      WCS.WorkEngineering/WebApi/Models/AGV/AgvResponseCode.cs
  22. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/Request/AgvCallbackRequest.cs
  23. 68 0
      WCS.WorkEngineering/WebApi/Models/AGV/Request/ContinueTaskRequest.cs
  24. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/Request/CopperLineAgvTaskStockInToIWmsRequest.cs
  25. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/Request/CopperLineAgvTaskStockOutToIWmsRequest.cs
  26. 99 6
      WCS.WorkEngineering/WebApi/Models/AGV/Request/GenAgvSchedulingTaskRequest.cs
  27. 25 0
      WCS.WorkEngineering/WebApi/Models/AGV/Response/ContinueTaskResponse.cs
  28. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/Response/GenAgvSchedulingTaskResponse.cs
  29. 1 1
      WCS.WorkEngineering/WebApi/Models/AGV/Response/agvCallbackResponse.cs
  30. 19 6
      WCS.WorkEngineering/WebApi/Startup.cs
  31. 20 2
      WCS.WorkEngineering/WorkStart.cs
  32. 31 0
      WCS.WorkEngineering/Worlds/DataCollectionWorld.cs

+ 18 - 18
ServiceCenter/Extensions/LinqExtension.cs

@@ -5,23 +5,23 @@
     /// </summary>
     public static class LinqExtension
     {
-        /// <summary>
-        /// 根据指定的属性返回集合中的非重复元素
-        /// </summary>
-        /// <remarks>不明白本方法是如何实现去重的</remarks>
-        /// <typeparam name="TSource">数据源的类型</typeparam>
-        /// <typeparam name="TKey">数据源需要进行筛选的属性</typeparam>
-        /// <param name="source">数据源</param>
-        /// <param name="keySelector">指定属性的函数表达式</param>
-        /// <returns></returns>
-        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
-        {
-            var seenKeys = new HashSet<TKey>();
-            foreach (var source1 in source)
-            {
-                if (seenKeys.Add(keySelector(source1)))
-                    yield return source1;
-            }
-        }
+        ///// <summary>
+        ///// 根据指定的属性返回集合中的非重复元素
+        ///// </summary>
+        ///// <remarks>不明白本方法是如何实现去重的</remarks>
+        ///// <typeparam name="TSource">数据源的类型</typeparam>
+        ///// <typeparam name="TKey">数据源需要进行筛选的属性</typeparam>
+        ///// <param name="source">数据源</param>
+        ///// <param name="keySelector">指定属性的函数表达式</param>
+        ///// <returns></returns>
+        //public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
+        //{
+        //    var seenKeys = new HashSet<TKey>();
+        //    foreach (var source1 in source)
+        //    {
+        //        if (seenKeys.Add(keySelector(source1)))
+        //            yield return source1;
+        //    }
+        //}
     }
 }

+ 5 - 3
ServiceCenter/ServiceCenter.csproj

@@ -10,9 +10,11 @@
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
     <PackageReference Include="PlcSiemens" Version="1.0.0.2" />
-    <PackageReference Include="WCS.Core" Version="1.0.0.8" />
-    <PackageReference Include="WCS.Entity" Version="1.0.1.7" />
-    <PackageReference Include="WCS.Entity.Protocol" Version="1.0.0.6" />
+    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
+    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.5.0" />
+    <PackageReference Include="WCS.Core" Version="1.0.0.9" />
+    <PackageReference Include="WCS.Entity" Version="1.0.1.9" />
+    <PackageReference Include="WCS.Entity.Protocol" Version="1.0.0.7" />
   </ItemGroup>
 
 </Project>

+ 79 - 89
WCS.Core/World.cs

@@ -1,17 +1,9 @@
 using FreeRedis;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
-using System.Drawing;
-using System.Linq;
 using System.Reflection;
 using System.Runtime.InteropServices;
-using System.Text;
 using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Xml.Schema; 
 
 namespace WCS.Core
 {
@@ -19,15 +11,18 @@ namespace WCS.Core
     /// 世界用来管理下属System的执行周期,此为默认世界。也可以通过继承此类创建多个不同世界,不同世界的执行周期相互独立,不受其它世界延迟干扰。
     /// </summary>
     [Description("默认世界")]
-    public abstract class World: DescriptionClass
+    public abstract class World : DescriptionClass
     {
         [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")]
         public static extern uint MM_BeginPeriod(uint uMilliseconds);
+
         [DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]
         public static extern uint MM_EndPeriod(uint uMilliseconds);
 
         #region Static
-        static List<World> _Worlds;
+
+        private static List<World> _Worlds;
+
         internal static List<World> Worlds
         {
             get
@@ -36,7 +31,7 @@ namespace WCS.Core
                 {
                     _Worlds = new List<World>();
                     //_Worlds.Add(new World());//默认世界
-                    var arr = Assembly.GetEntryAssembly().GetTypes().Where(v => typeof(World).IsAssignableFrom(v)).Select(v => Activator.CreateInstance(v)).OfType<World>().ToArray();//自定义世界
+                    var arr = AppDomain.CurrentDomain.GetAssemblies().Select(v => v.GetTypes()).SelectMany(v => v).Where(v => typeof(World).IsAssignableFrom(v) && v != typeof(World)).Select(v => Activator.CreateInstance(v)).OfType<World>().ToArray();//自定义世界
                     _Worlds.AddRange(arr);
                 }
                 return _Worlds;
@@ -61,13 +56,13 @@ namespace WCS.Core
         }
 
         public static void StartAll()
-        { 
+        {
             MM_BeginPeriod(1);
             Worlds.ForEach(w => w.Init());
             foreach (World w in Worlds)
             {
                 if (w.SystemTypes.Length == 0)
-                    continue; 
+                    continue;
                 w.Start();
             }
             var arr = Worlds.SelectMany(v => v.SystemGroups).SelectMany(v => v.Value)
@@ -85,38 +80,38 @@ namespace WCS.Core
             }
         }
 
-
-
         public static void StopAll()
         {
             MM_EndPeriod(1);
             foreach (World w in Worlds)
                 w.Stop();
         }
-        #endregion
+
+        #endregion Static
 
         #region Dynamic
+
         public bool Stoped;
-        Dictionary<Type, int> TypeOrder = new Dictionary<Type, int>();
-        Dictionary<int, List<SystemBase>> SystemGroups = new Dictionary<int, List<SystemBase>>();
+        private Dictionary<Type, int> TypeOrder = new Dictionary<Type, int>();
+        private Dictionary<int, List<SystemBase>> SystemGroups = new Dictionary<int, List<SystemBase>>();
         protected Type[] SystemTypes;
-          
 
         /// <summary>
         /// 周期最小间隔时间(毫秒)
         /// </summary>
-        protected abstract int Interval {
+        protected abstract int Interval
+        {
             get;
         }
 
         public World()
         {
-            SystemTypes = GetSystemTypes(); 
+            SystemTypes = GetSystemTypes();
         }
 
         protected virtual Type[] GetSystemTypes()
-        { 
-            var sysTypes = Assembly.GetEntryAssembly().GetTypes()
+        {
+            var sysTypes = AppDomain.CurrentDomain.GetAssemblies().Select(v => v.GetTypes()).SelectMany(v => v)
                 .Where(v => !v.IsAbstract)
                 .Where(v => typeof(SystemBase).IsAssignableFrom(v))
                 .Where(v =>
@@ -128,19 +123,16 @@ namespace WCS.Core
                         return true;
                     return false;
                 }).ToArray();
-            return sysTypes; 
+            return sysTypes;
         }
 
-
         //public List<Device> Devices;
-        
 
         /// <summary>
         /// 初始化,实例化世界下的所有系统
         /// </summary>
         public virtual void Init()
         {
-         
             try
             {
                 //Devices = Protocols.Generate(this);
@@ -159,7 +151,7 @@ namespace WCS.Core
                     var sysArr = g.Select(v =>
                     {
                         var sysDesc = v.Key.GetCustomAttribute<DescriptionAttribute>()?.Description;
-                        Ltc.SetChannel(new Channel { World = Description, Stage="Init", System = sysDesc ?? v.Key.Name, Item = "构造" });
+                        Ltc.SetChannel(new Channel { World = Description, Stage = "Init", System = sysDesc ?? v.Key.Name, Item = "构造" });
                         return Activator.CreateInstance(v.Key);
                     }).OfType<SystemBase>().ToArray();
                     list.AddRange(sysArr);
@@ -167,20 +159,20 @@ namespace WCS.Core
                 }
             }
             catch (Exception ex)
-            { 
+            {
                 throw;
             }
-            finally 
-            { 
+            finally
+            {
             }
         }
 
-        int Set(Type type,int level)
+        private int Set(Type type, int level)
         {
             if (!SystemTypes.Contains(type))
                 throw new Exception($"OrderAttribute设置错误,与目标不属于同一世界。类型:{type}。");
             if (level > 10)
-            { 
+            {
                 throw new Exception($"OrderAttribute设置错误,导致死循环。类型:{type}。");
             }
             var attr = type.GetCustomAttribute<OrderAttribute>();
@@ -197,17 +189,17 @@ namespace WCS.Core
             return TypeOrder[type];
         }
 
-         /// <summary>
-         /// 开启世界主循环
-         /// </summary>
+        /// <summary>
+        /// 开启世界主循环
+        /// </summary>
         public void Start()
-        { 
-            Stoped = false; 
+        {
+            Stoped = false;
             Task.Run(Loop);//不要使用Thread,可以使用ThreadPool
         }
 
-        void Loop()
-        { 
+        private void Loop()
+        {
             var sw = new Stopwatch();
             while (!Stoped)
             {
@@ -223,13 +215,13 @@ namespace WCS.Core
                 //sw.Start();
                 if (ms > 0)
                 {
-                    Thread.Sleep(ms);//不要使用Task.Delay().Wait()      
+                    Thread.Sleep(ms);//不要使用Task.Delay().Wait()
                 }
                 //sw.Stop();
                 //var total = sw.ElapsedMilliseconds;
                 wt.Total = workTimes;
                 FrameInfo(wt);
-            } 
+            }
         }
 
         public void Stop()
@@ -237,11 +229,11 @@ namespace WCS.Core
             Stoped = true;
         }
 
-        void Update(List<WorkTimes> list)
+        private void Update(List<WorkTimes> list)
         {
             var wt = new WorkTimes();
             wt.Key = "读取PLC数据";
-            var sw=new Stopwatch();
+            var sw = new Stopwatch();
             sw.Start();
             LoadPlcData(wt.Items);
             sw.Stop();
@@ -254,11 +246,11 @@ namespace WCS.Core
             DoLogics(wt.Items);
             sw.Stop();
             wt.Total = sw.ElapsedMilliseconds;
-            list.AddSafe(wt); 
+            list.AddSafe(wt);
         }
-         
-        void LoadPlcData(List<WorkTimes> list)
-        { 
+
+        private void LoadPlcData(List<WorkTimes> list)
+        {
             Parallel.ForEach(this.GetDataBlocks(), db =>
             {
                 var channel = new Channel
@@ -273,34 +265,35 @@ namespace WCS.Core
                 try
                 {
                     db.RefreshData();
-                } 
+                }
                 catch (Exception ex)
-                { 
-                    this.Ex().Publish(channel, ex.GetBaseException().Message); 
+                {
+                    this.Ex().Publish(channel, ex.GetBaseException().Message);
                 }
                 sw.Stop();
-                list.AddSafe(new WorkTimes { Key = $"{db.Entity.PLCInfo.IP}/{db.Entity.No}", Total = sw.ElapsedMilliseconds }); 
-            });  
+                list.AddSafe(new WorkTimes { Key = $"{db.Entity.PLCInfo.IP}/{db.Entity.No}", Total = sw.ElapsedMilliseconds });
+            });
         }
 
-        void DoLogics(List<WorkTimes> list)
-        {   
-            foreach(var group in SystemGroups)
+        private void DoLogics(List<WorkTimes> list)
+        {
+            foreach (var group in SystemGroups)
             {
-                var wt=new WorkTimes();
+                var wt = new WorkTimes();
                 wt.Key = $"组{group.Key}";
                 var sw = new Stopwatch();
-                sw.Restart(); 
+                sw.Restart();
                 Parallel.ForEach(group.Value, sys =>
                 {
-                    var wt2=new WorkTimes();
+                    var wt2 = new WorkTimes();
                     wt2.Key = sys.Description;
                     var sw2 = new Stopwatch();
                     sw2.Start();
                     try
                     {
                         sys.Update(wt2.Items);
-                    }catch (Exception ex)
+                    }
+                    catch (Exception ex)
                     {
                         Console.ForegroundColor = ConsoleColor.Red;
                         Console.WriteLine(ex.GetBaseException().Message);
@@ -309,25 +302,23 @@ namespace WCS.Core
                     sw2.Stop();
                     wt2.Total = sw2.ElapsedMilliseconds;
                     list.AddSafe(wt2);
-                }); 
-                sw.Stop();  
-                wt.Total= sw.ElapsedMilliseconds;
+                });
+                sw.Stop();
+                wt.Total = sw.ElapsedMilliseconds;
                 //list.AddSafe(wt);
-            } 
+            }
         }
-         
+
         protected virtual void BeforeUpdate()
-        { 
-            
+        {
         }
 
         protected virtual void AfterUpdate()
         {
-
         }
 
-        #endregion
-         
+        #endregion Dynamic
+
         public T GetSystem<T>() where T : SystemBase
         {
             var sys = Systems.Where(v => v.GetType() == typeof(T)).FirstOrDefault() as T;
@@ -338,16 +329,17 @@ namespace WCS.Core
 
         public SystemBase[] Systems
         {
-            get {
+            get
+            {
                 return SystemGroups.SelectMany(v => v.Value).ToArray();
             }
         }
-         
+
         protected virtual void FrameInfo(WorkTimes wt)
         {
             if (wt.Total > this.Interval)
             {
-                Console.ForegroundColor = ConsoleColor.Red; 
+                Console.ForegroundColor = ConsoleColor.Red;
             }
             Console.WriteLine(wt.GetInfo());
             Console.ResetColor();
@@ -358,12 +350,11 @@ namespace WCS.Core
             OnLog(Ltc.GetChannel(), log);
         }
 
-        internal protected abstract void OnError(Channel channel, Exception exception);
-        internal protected abstract void OnInternalLog(Channel channel, string msg);
+        protected internal abstract void OnError(Channel channel, Exception exception);
 
-        protected abstract void OnLog(Channel channel, object logObj);
+        protected internal abstract void OnInternalLog(Channel channel, string msg);
 
-        
+        protected abstract void OnLog(Channel channel, object logObj);
 
         protected abstract IEnumerable<string> GetChannelMsg(Channel channel);
 
@@ -372,21 +363,19 @@ namespace WCS.Core
             var channel = Ltc.GetChannel();
             var msgs = GetChannelMsg(channel);
             var msg = string.Join("\n", msgs);
-            this.Ex().Publish(channel,msg);
+            this.Ex().Publish(channel, msg);
         }
     }
 
     public interface ILog
-    { 
-        
+    {
     }
 
-
     public class WorldEx : EntityEx<World>
-    { 
-        RedisClient Redis = new RedisClient(Configs.DebugRedisUrl);
-        List<string> ChannelList = new List<string>();
-        DateTime SubTime = DateTime.Now;
+    {
+        private RedisClient Redis = new RedisClient(Configs.DebugRedisUrl);
+        private List<string> ChannelList = new List<string>();
+        private DateTime SubTime = DateTime.Now;
 
         public WorldEx(World ent) : base(ent)
         {
@@ -410,7 +399,7 @@ namespace WCS.Core
             var flag = false;
             lock (ChannelList)
             {
-                flag=ChannelList.Any(v =>
+                flag = ChannelList.Any(v =>
                 {
                     var b = Regex.Match(channel.ToString(), $"^{v.Replace("*", ".*")}$");
                     return b.Success;
@@ -424,7 +413,7 @@ namespace WCS.Core
     public class WorkTimes
     {
         public string Key { get; set; } = "";
-        public long Total { get; set; } 
+        public long Total { get; set; }
         public List<WorkTimes> Items { get; set; } = new List<WorkTimes>();
 
         public override string ToString()
@@ -444,17 +433,18 @@ namespace WCS.Core
     public abstract class AttrClass<T> where T : Attribute
     {
         public T? Attr { get; private set; }
+
         public AttrClass()
         {
             Attr = GetType().GetCustomAttribute<T>();
         }
     }
 
-    public abstract class DescriptionClass:AttrClass<DescriptionAttribute> 
+    public abstract class DescriptionClass : AttrClass<DescriptionAttribute>
     {
         public string Description
         {
-            get 
+            get
             {
                 if (Attr != null)
                     return Attr.Description;

+ 7 - 5
WCS.Entity.Protocol/SRM/SrmEnum.cs

@@ -73,22 +73,22 @@ namespace WCS.Entity.Protocol.SRM
         /// <summary>
         ///  自动
         /// </summary>
-        Automatic = 0,
+        Automatic = 1,
 
         /// <summary>
         ///  半自动
         /// </summary>
-        SemiAutomatic = 1,
+        SemiAutomatic = 2,
 
         /// <summary>
         ///  手动
         /// </summary>
-        Manual = 2,
+        Manual = 3,
 
         /// <summary>
         ///  保持维修
         /// </summary>
-        KeepInRepair
+        KeepInRepair = 4
     }
 
     /// <summary>
@@ -145,6 +145,7 @@ namespace WCS.Entity.Protocol.SRM
     /// <summary>
     /// 堆垛机状态
     /// </summary>
+    [Flags]
     public enum SrmStatus : ushort
     {
         /// <summary>
@@ -232,6 +233,7 @@ namespace WCS.Entity.Protocol.SRM
     /// 堆垛机报警项
     /// </summary>
     [Flags]
-    public enum SrmAlarm : ulong { 
+    public enum SrmAlarm : ulong
+    {
     }
 }

+ 1 - 1
WCS.Entity.Protocol/Station/IStation520.cs

@@ -32,7 +32,7 @@ namespace WCS.Entity.Protocol.Station
         ModeEunm Mode { get; set; }
 
         /// <summary>
-        /// 指令类型
+        /// 指令类型 1
         /// </summary>
         [Description("指令类型")]
         short CmdType { get; set; }

+ 6 - 0
WCS.Entity/WCS_TaskInfo.cs

@@ -131,6 +131,12 @@ namespace WCS.Entity
         [SugarColumn(ColumnDescription = "高度", IsNullable = true)]
         public short Height { get; set; }
 
+        /// <summary>
+        ///  重量
+        /// </summary>
+        [SugarColumn(ColumnDescription = "重量", IsNullable = true)]
+        public float Weight { get; set; }
+
         /// <summary>
         /// WMS任务号
         /// </summary>

+ 8 - 4
WCS.Service/PLCAccessors/PLCAccessorsCreater.cs

@@ -16,10 +16,14 @@ namespace WCS.Service.PLCAccessors
         /// <exception cref="Exception"> </exception>
         public IPLCAccessor Create(PLCInfo data)
         {
-            if (data.Type == PLCType.Siemens)
-                return new SiemensS7PLC(data.IP, data.Port, data.Rack, data.Slot);
-            else
-                throw new Exception("不支持此PLC");
+            switch (data.Type)
+            {
+                case PLCType.Siemens:
+                    return new SiemensS7PLC(data.IP, data.Port, data.Rack, data.Slot);
+
+                default:
+                    return new VitrualRedisPLC(data, "127.0.0.1,database=1,prefix=Sorting:");
+            }
         }
     }
 }

+ 7 - 18
WCS.Service/Worker.cs

@@ -7,10 +7,9 @@ using SqlSugar;
 using System.Text;
 using WCS.Core;
 using WCS.Entity;
-using WCS.Entity.Protocol.BCR;
 using WCS.Entity.Protocol.Station;
-using WCS.Service.Systems;
 using WCS.WorkEngineering;
+using WCS.WorkEngineering.Extensions;
 
 namespace WCS.Service
 {
@@ -153,17 +152,16 @@ namespace WCS.Service
 
             //    //从现有结构解析出需要的结构
             //    var list = new List<PLCData>();
-            //    SqlSugarHelper.Do(db =>
+
+            //    DeviceExtension.ProtocolInfos.ForEach(item =>
             //    {
-            //        var _db = db.Connect;
-            //        var dataBlocks = _db.Queryable<WCS_PlcDataBlock>().Includes(v => v.PLC).ToList();
-            //        list.AddRange(dataBlocks.Select(dataBlock => new PLCData()
+            //        list.AddRange(new PLCData()
             //        {
-            //            IP = dataBlock.PLC.IP,
-            //            DB = dataBlock.NO,
+            //            IP = item.DBInfo.PLCInfo.IP,
+            //            DB = item.DBInfo.No,
             //            Length = dataBlock.Length,
             //            DataLength = dataBlock.DataLength,
-            //        }));
+            //        });
             //    });
             //    PlcData.Init(plcDataConnectionString).InitPlcData(list);
 
@@ -187,15 +185,6 @@ namespace WCS.Service
                 #endregion 唤醒所有的世界
 
                 _logger.LogInformation("WCS启动成功");
-
-                #region 启用数据采集器
-
-                while (true)
-                {
-                    World.GetSystemInstance<DataCollectionSysyem>().Invoke(true);
-                }
-
-                #endregion 启用数据采集器
             }
             catch (Exception ex)
             {

+ 29 - 0
WCS.Service/Worlds/initWorld.cs

@@ -0,0 +1,29 @@
+using WCS.Core;
+
+namespace WCS.Service.Worlds
+{
+    public class initWorld : World
+    {
+        protected override int Interval => 300;
+
+        protected override IEnumerable<string> GetChannelMsg(Channel channel)
+        {
+            throw new NotImplementedException();
+        }
+
+        protected override void OnError(Channel channel, Exception exception)
+        {
+            throw new NotImplementedException();
+        }
+
+        protected override void OnInternalLog(Channel channel, string msg)
+        {
+            throw new NotImplementedException();
+        }
+
+        protected override void OnLog(Channel channel, object logObj)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

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

@@ -10,6 +10,8 @@ namespace WCS.WorkEngineering.Extensions
     {
         #region 设备类型
 
+        public static List<ProtocolInfo> ProtocolInfos = new List<ProtocolInfo>();
+
         /// <summary>
         ///  是否是巷道
         /// </summary>
@@ -42,6 +44,7 @@ namespace WCS.WorkEngineering.Extensions
                     }
                 }
             };
+            ProtocolInfos.Add(info);
             device.AddProtocol<T>(info);
         }
 

+ 2 - 1
WCS.WorkEngineering/Systems/AgvSystems.cs

@@ -5,7 +5,8 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using WCS.Core;
-using WCS.WorkEngineering.WebApi.Models.AGV;
+using WCS.WorkEngineering.WebApi.Models.AGV.Request;
+using WCS.WorkEngineering.WebApi.Models.AGV.Response;
 using WCS.WorkEngineering.Worlds;
 
 namespace WCS.WorkEngineering.Systems

+ 127 - 0
WCS.WorkEngineering/Systems/DeviceWriteSystem.cs

@@ -0,0 +1,127 @@
+using WCS.Core;
+using WCS.Entity.Protocol.SRM;
+using WCS.Entity.Protocol.Station;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Worlds;
+
+namespace WCS.WorkEngineering.Systems
+{
+    /// <summary>
+    ///  设备信息写入接口
+    /// </summary>
+    [BelongTo(typeof(MainWorld))]
+    public class DeviceWriteSystem : ServiceSystem<DeviceWriteInfo>
+    {
+        /// <summary>
+        /// 所有的站台
+        /// </summary>
+        private Dictionary<string, Station> Convs;
+
+        private Dictionary<string, SRM> Srms;
+
+        /// <summary>
+        ///  构造函数
+        /// </summary>
+        public DeviceWriteSystem()
+        {
+            Convs = Device.All.Where(v => v.HasProtocol<IStation520>()).Select(v => new Station(v, this.World)).ToDictionary(v => v.Entity.Code, v => v);
+            Srms = Device.All.Where(v => v.HasProtocol<ISRM520>()).Select(v => new SRM(v, this.World)).ToDictionary(v => v.Entity.Code, v => v);
+        }
+
+        protected override void Do(DeviceWriteInfo info)
+        {
+            Type? type = null;
+            object? obj = null;
+            switch (info.DeviceType)
+            {
+                case DeviceTypeEnum.SRM:
+                    var srm = Srms[info.Code];
+                    type = typeof(ISRM520).Assembly.GetTypes().Where(v => v.Name == info.Protocol).First();
+                    obj = srm.Entity.Protocol(type, this.World);
+
+                    break;
+
+                case DeviceTypeEnum.DEV:
+                    var conv = Convs[info.Code];
+                    type = typeof(IStation520).Assembly.GetTypes().Where(v => v.Name == info.Protocol).First();
+                    obj = conv.Entity.Protocol(type, this.World);
+
+                    break;
+
+                case DeviceTypeEnum.BCR:
+                    break;
+
+                case DeviceTypeEnum.RGV:
+                    break;
+            }
+            var p = type.GetProperty(info.Property);
+            if (p.PropertyType.IsEnum)
+            {
+                var value = Enum.Parse(p.PropertyType, info.Value);
+                p.SetValue(obj, value);
+            }
+            else
+            {
+                var value = Convert.ChangeType(info.Value, p.PropertyType);
+                p.SetValue(obj, value);
+            }
+        }
+    }
+
+    /// <summary>
+    /// 设备写入信息
+    /// </summary>
+    public class DeviceWriteInfo
+    {
+        /// <summary>
+        ///  设备类型
+        /// </summary>
+        public DeviceTypeEnum DeviceType { get; set; }
+
+        /// <summary>
+        /// 设备号
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        ///  协议
+        /// </summary>
+        public string Protocol { get; set; }
+
+        /// <summary>
+        /// 字段明
+        /// </summary>
+        public string Property { get; set; }
+
+        /// <summary>
+        ///  值
+        /// </summary>
+        public string Value { get; set; }
+    }
+
+    /// <summary>
+    ///  设备类型接口
+    /// </summary>
+    public enum DeviceTypeEnum
+    {
+        /// <summary>
+        ///  堆垛机
+        /// </summary>
+        SRM = 1,
+
+        /// <summary>
+        ///  输送线
+        /// </summary>
+        DEV = 2,
+
+        /// <summary>
+        ///  扫码器
+        /// </summary>
+        BCR = 3,
+
+        /// <summary>
+        /// RGV小车
+        /// </summary>
+        RGV = 4,
+    }
+}

+ 64 - 0
WCS.WorkEngineering/Systems/InboundSiteInteractionSystem.cs

@@ -0,0 +1,64 @@
+using ServiceCenter.SqlSugars;
+using System.ComponentModel;
+using WCS.Core;
+using WCS.Entity;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Worlds;
+using WCS.WorkEngineering.Worlds.Logs;
+using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
+
+namespace WCS.WorkEngineering.Systems
+{
+    /// <summary>
+    ///  入站站点交互系统
+    /// </summary>
+    //[BelongTo(typeof(MainWorld))]
+    [Description("入站站点交互系统")]
+    public class InboundSiteInteractionSystem : DeviceSystem<Station>
+    {
+        protected override bool ParallelDo => true;
+
+        protected override bool SaveLogsToFile => true;
+
+        private BCRList BCRS = new BCRList();
+
+        public InboundSiteInteractionSystem()
+        {
+            BCRS = Device.All.Where(v => v.HasFlag(DeviceFlags.扫码)).Select(v => new BCR(v, World)).ToList() as BCRList;
+        }
+
+        public override void Do(Station obj)
+        {
+            obj.StorageStationIsForbid();
+            //判断凭证号是否一致
+            if (obj.Data.VoucherNo != obj.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521{obj.Data2.VoucherNo}", LogLevelEnum.High);
+            //设备是否停止运行
+            if (obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
+
+            //获取RFID
+            var barcode = BCRS.GetBCRCode(obj.Entity.Code);
+
+            //TODO:上抛WMS任务号与RFID,但不需要跟据上抛结果进行任何处理
+            WCS_TaskInfo task = null;
+            var result = SqlSugarHelper.Do(db =>
+               {
+                   //跟据RFID获取对应的任务
+                   task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.BarCode == barcode) ?? throw new KnownException($"未找到RFID:{barcode}对应WCS任务", LogLevelEnum.High);
+                   if (task.Status != Entity.TaskStatus.AGVExecution) throw new KnownException($"任务:{task.ID}状态不是AGV执行中,请检查异常原因", LogLevelEnum.High);
+
+                   //获取称重
+                   //task.Weight = obj.Data4.Weight;
+                   task.Status = Entity.TaskStatus.ConveyorExecution;
+                   db.Default.Updateable(task).AddQueue();
+                   //task.AddWCS_TASK_DTL(db, obj.Entity.Code, "SRM", $"状态更新为{Entity.TaskStatus.ConveyorExecution},记录重量:{obj.Data4.Width}.等待分配货位后堆垛机进行取货");
+                   db.Default.SaveQueues();
+               });
+            if (task == null || !result) throw new KnownException("数据更新错误", LogLevelEnum.High);
+        }
+
+        public override bool Select(Device dev)
+        {
+            return dev.HasFlag(DeviceFlags.巷道口) && dev.HasFlag(DeviceFlags.入库);
+        }
+    }
+}

+ 4 - 1
WCS.WorkEngineering/Systems/OutboundSiteInteractionSystems.cs

@@ -1,11 +1,14 @@
 using WCS.Core;
 using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Worlds;
+using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
 
 namespace WCS.WorkEngineering.Systems
 {
     /// <summary>
     /// 出库站台交互
     /// </summary>
+    //[BelongTo(typeof(MainWorld))]
     public class OutboundSiteInteractionSystems : DeviceSystem<Station>
     {
         protected override bool ParallelDo => true;
@@ -41,7 +44,7 @@ namespace WCS.WorkEngineering.Systems
 
         public override bool Select(Device dev)
         {
-            throw new NotImplementedException();
+            return dev.HasFlag(DeviceFlags.巷道口) && dev.HasFlag(DeviceFlags.出库);
         }
     }
 }

+ 8 - 2
WCS.WorkEngineering/Systems/SrmSystems.cs

@@ -46,7 +46,7 @@ namespace WCS.WorkEngineering.Systems
                 PickUpDevices.Add(srm.Code, item.Targets.Where(v => v.HasFlag(DeviceFlags.输送机)).Select(v => new Station(v, this.World)).ToList());
                 //放货设备
                 srm = item.Sources.Where(v => v.HasFlag(DeviceFlags.堆垛机)).FirstOrDefault();
-                PutDevices.Add(srm.Code, item.Sources.Where(v => v.HasFlag(DeviceFlags.堆垛机)).Select(v => new Station(v, this.World)).ToList());
+                PutDevices.Add(srm.Code, item.Sources.Where(v => v.HasFlag(DeviceFlags.输送机)).Select(v => new Station(v, this.World)).ToList());
             }
         }
 
@@ -56,10 +56,16 @@ namespace WCS.WorkEngineering.Systems
 
         public override void Do(SRM obj)
         {
+            if (obj.Entity.Code == "SRM1")
+            {
+                obj.Data.TaskType = SrmTaskTypeEnum.MoveTask;
+            }
+
             //判断堆垛机是否报警
             if (obj.Data2.Status.HasFlag(SrmStatus.Alarm)) throw new KnownException(obj.Data3.Alarm.ToString(), LogLevelEnum.High);
 
             //判断DB520 完成任务确认清除信号 是否为1
+
             if (obj.Data.OkAck == 1) throw new KnownException("任务完成确认信号未清除", LogLevelEnum.Mid);
 
             //判断完成任务号是否大于0
@@ -270,7 +276,7 @@ namespace WCS.WorkEngineering.Systems
                     taskInfo = task;
                     db.Default.SaveQueues();
                 });
-
+                if (taskInfo == null || !result) throw new KnownException("数据更新错误", LogLevelEnum.High);
                 obj.Data.TaskNumber = taskInfo.ID;
                 obj.Data.SLine = addrFrom[0].ToShort();
                 obj.Data.SCol = addrFrom[1].ToShort();

+ 0 - 48
WCS.WorkEngineering/Systems/StorageSysyem.cs

@@ -1,48 +0,0 @@
-using System.ComponentModel;
-using WCS.Core;
-using WCS.Entity.Protocol.BCR;
-using WCS.WorkEngineering.Extensions;
-using WCS.WorkEngineering.WebApi.Controllers;
-using WCS.WorkEngineering.Worlds;
-using WCS.WorkEngineering.Worlds.Logs;
-
-namespace WCS.WorkEngineering.Systems
-{
-    /// <summary>
-    /// </summary>
-    [BelongTo(typeof(SortingMainLineWorld))]
-    [Description("主线扫码")]
-    public class StorageSysyem : DeviceSystem<Station>
-    {
-        protected override bool ParallelDo => true;
-
-        protected override bool SaveLogsToFile => true;
-
-        private BCRList BCRS = new BCRList();
-
-        public StorageSysyem()
-        {
-            BCRS = Device.All.Where(v => v.HasProtocol(typeof(IBCR81))).Select(v => new BCR(v, World)).ToList() as BCRList;
-        }
-
-        public override void Do(Station obj)
-        {
-            obj.StorageStationIsForbid();
-            //判断凭证号是否一致
-            if (obj.Data.VoucherNo != obj.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521{obj.Data2.VoucherNo}", LogLevelEnum.High);
-            //设备是否停止运行
-            if (obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
-
-            //获取条码
-            var barcode = BCRS.GetBCRCode(obj.Entity.Code);
-
-            //获取入库任务
-            var info = WmsApi.I_WCS_GetInTask(barcode, obj.Entity.Code, true);
-        }
-
-        public override bool Select(Device dev)
-        {
-            return new int[] { 1701, 2101, 1717, 2117 }.Contains(int.Parse(dev.Code));
-        }
-    }
-}

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

@@ -4,11 +4,16 @@
     <TargetFramework>net7.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
   </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
-    <PackageReference Include="ServiceCenter" Version="1.0.1.15" />
+    <PackageReference Include="ServiceCenter" Version="1.0.2.4" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\WCS.Entity.Protocol\WCS.Entity.Protocol.csproj" />
   </ItemGroup>
 
 </Project>

+ 58 - 0
WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs

@@ -0,0 +1,58 @@
+using ServiceCenter.WebApi;
+using WCS.WorkEngineering.WebApi.Models.AGV;
+using WCS.WorkEngineering.WebApi.Models.AGV.Request;
+using WCS.WorkEngineering.WebApi.Models.AGV.Response;
+using WCS.WorkEngineering.Worlds.Logs;
+
+namespace WCS.WorkEngineering.WebApi.Controllers
+{
+    /// <summary>
+    ///  AGV接口
+    /// </summary>
+    public static class AgvApi
+    {
+        /// <summary>
+        /// AGV地址
+        /// </summary>
+        public static string AgvUrl = null!;
+
+        //public static GenAgvSchedulingTaskResponse GenAgvSchedulingTask()
+        //{
+        //    var res = APICaller.CallApi2<ContinueTaskResponse>(AgvUrl + "/hikRpcService/continueTask", new ContinueTaskRequest
+        //    {
+        //        reqCode = Guid.NewGuid().ToString(),
+        //        taskCode = taskCode,
+        //        type = "00",
+        //        nextPositionCode = nextPositionCode
+        //    });
+        //    if (res.code != AgvContinueTaskResponseCode.Success)
+        //    {
+        //        throw new KnownException(res.message, LogLevelEnum.High);
+        //    }
+        //    return res;
+        //}
+
+        /// <summary>
+        ///  继续执行任务
+        /// </summary>
+        /// <param name="taskCode">AGV任务号</param>
+        /// <param name="nextPositionCode">下一个地址</param>
+        /// <returns>接口返回结果</returns>
+        /// <exception cref="KnownException"></exception>
+        public static ContinueTaskResponse ContinueTask(string taskCode, string nextPositionCode)
+        {
+            var res = APICaller.CallApi2<ContinueTaskResponse>(AgvUrl + "/hikRpcService/continueTask", new ContinueTaskRequest
+            {
+                reqCode = Guid.NewGuid().ToString(),
+                taskCode = taskCode,
+                type = "00",
+                nextPositionCode = nextPositionCode
+            });
+            if (res.code != AgvResponseCode.Success)
+            {
+                throw new KnownException(res.message, LogLevelEnum.High);
+            }
+            return res;
+        }
+    }
+}

+ 3 - 2
WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -1,7 +1,8 @@
 using Microsoft.AspNetCore.Mvc;
 using WCS.Core;
 using WCS.WorkEngineering.Systems;
-using WCS.WorkEngineering.WebApi.Models.AGV;
+using WCS.WorkEngineering.WebApi.Models.AGV.Request;
+using WCS.WorkEngineering.WebApi.Models.AGV.Response;
 
 namespace WCS.WorkEngineering.WebApi.Controllers
 {
@@ -9,7 +10,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
     /// AGV相关接口控制器
     /// </summary>
     [ApiController]
-    [Route("[controller]/[action]")]
+    [Route("api/[controller]/[action]")]
     public class AgvController : ControllerBase
     {
         /// <summary>

+ 51 - 0
WCS.WorkEngineering/WebApi/Controllers/WcsController.cs

@@ -0,0 +1,51 @@
+using Microsoft.AspNetCore.Mvc;
+using WCS.Core;
+using WCS.WorkEngineering.Systems;
+
+namespace WCS.WorkEngineering.WebApi.Controllers
+{
+    /// <summary>
+    /// WCS相关接口控制器
+    /// </summary>
+    [ApiController]
+    [Route("api/[controller]/[action]")]
+    public class WcsController : ControllerBase, IDeviceWriter
+    {
+        /// <summary>
+        ///  设备信息写入接口
+        /// </summary>
+        /// <param name="deviceType">需要写入信息的设备类型</param>
+        /// <param name="devCode">设备编号</param>
+        /// <param name="protocol">设备协议类名</param>
+        /// <param name="propName">写入字段名</param>
+        /// <param name="value">值</param>
+        [HttpPost]
+        public void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value)
+        {
+            World.GetSystemInstance<DeviceWriteSystem>().Invoke(new DeviceWriteInfo
+            {
+                DeviceType = deviceType,
+                Code = devCode,
+                Protocol = protocol,
+                Property = propName,
+                Value = value
+            });
+        }
+
+        /// <summary>
+        ///  获取设备配置信息接口
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet]
+        public List<Device> GetDeviceList()
+        {
+            return Device.All.ToList();
+        }
+    }
+
+    public interface IDeviceWriter
+    {
+        [HttpPost]
+        void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value);
+    }
+}

+ 28 - 0
WCS.WorkEngineering/WebApi/Models/AGV/AgvResponseCode.cs

@@ -0,0 +1,28 @@
+namespace WCS.WorkEngineering.WebApi.Models.AGV
+{
+    /// <summary>
+    ///  AGV 返回结果code值枚举
+    /// </summary>
+    public class AgvResponseCode
+    {
+        /// <summary>
+        ///  成功
+        /// </summary>
+        public static string Success { get; set; } = "0";
+
+        /// <summary>
+        ///  失败
+        /// </summary>
+        public static string Fail { get; set; } = "1";
+
+        /// <summary>
+        ///  重复提交
+        /// </summary>
+        public static string Repeat { get; set; } = "6";
+
+        /// <summary>
+        ///  失败,未知异常
+        /// </summary>
+        public static string Error { get; set; } = "99";
+    }
+}

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

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

+ 68 - 0
WCS.WorkEngineering/WebApi/Models/AGV/Request/ContinueTaskRequest.cs

@@ -0,0 +1,68 @@
+namespace WCS.WorkEngineering.WebApi.Models.AGV.Request
+{
+    /// <summary>
+    /// Agv继续执行任务请求参数
+    /// </summary>
+    public class ContinueTaskRequest
+    {
+        /// <summary>
+        ///  请求编号,每个请求都要一个唯一编号, 同一个请求重复提交, 使用同一编号。
+        /// </summary>
+        public string reqCode { get; set; }
+
+        /// <summary>
+        ///  请求时间截 格式: “yyyy-MM-dd HH:mm:ss”。
+        /// </summary>
+        public string reqTime { get; set; }
+
+        /// <summary>
+        ///  客户端编号,如PDA,HCWMS等。
+        /// </summary>
+        public string clientCode { get; set; }
+
+        /// <summary>
+        ///  令牌号, 由调度系统颁发。
+        /// </summary>
+        public string tokenCode { get; set; }
+
+        /// <summary>
+        ///  工作位,与RCS-2000端配置的位置名称一致。
+        /// </summary>
+        public string wbCode { get; set; }
+
+        /// <summary>
+        ///  货架号,采用货架号触发的方式。
+        /// </summary>
+        public string podCode { get; set; }
+
+        /// <summary>
+        ///  AGV编号,采用 AGV编号触发的方式。
+        /// </summary>
+        public string agvCode { get; set; }
+
+        /// <summary>
+        ///  任务单号,选填, 不填系统自动生 成,必须为 64 位 UUID
+        /// </summary>
+        public string taskCode { get; set; }
+
+        /// <summary>
+        ///  下一个子任务的序列,指定第几个子任务开始执行,校验子任务执行是否正确。不填默认执行下一个子任务。
+        /// </summary>
+        public string taskSeq { get; set; }
+
+        /// <summary>
+        ///  下一个位置信息,在任务类型中配置外部设置时需要传入,否则不需要设置。待现场地图部署、配置完成后可获取
+        /// </summary>
+        public object nextPositionCode { get; set; }
+
+        /// <summary>
+        ///  根据type填写,呼叫站点/策略编号等
+        /// </summary>
+        public string positionCode { get; set; }
+
+        /// <summary>
+        /// 对象类型定义: 00:代表 nextPositionCode是一个位置 02:代表nextPositionCode是一个策略
+        /// </summary>
+        public string type { get; set; }
+    }
+}

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

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

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

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

+ 99 - 6
WCS.WorkEngineering/WebApi/Models/AGV/GenAgvSchedulingTaskRequest.cs → WCS.WorkEngineering/WebApi/Models/AGV/Request/GenAgvSchedulingTaskRequest.cs

@@ -1,84 +1,177 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace WCS.WorkEngineering.WebApi.Models.AGV
+namespace WCS.WorkEngineering.WebApi.Models.AGV.Request
 {
+    /// <summary>
+    ///  生成任务单接口
+    /// </summary>
     public class GenAgvSchedulingTaskRequest
     {
         /// <summary>
         /// 请求编号,每个请求都要一个唯一编号, 同一个请求重复提交, 使用同一编号。
         /// </summary>
         public string reqCode { get; set; }
+
         /// <summary>
         /// 请求时间截 格式: “yyyy-MM-dd HH:mm:ss”
         /// </summary>
         public string reqTime { get; set; }
+
         /// <summary>
         /// 客户端编号,如PDA,HCWMS等
         /// </summary>
         public string clientCode { get; set; }
+
         /// <summary>
         /// 令牌号, 由调度系统颁发
         /// </summary>
         public string tokenCode { get; set; }
+
         /// <summary>
         /// 任务类型
         /// </summary>
         public string taskTyp { get; set; }
+
         /// <summary>
         /// 容器类型(叉车/CTU专用)叉车项目必传
         /// </summary>
         public string ctnrTyp { get; set; }
+
         /// <summary>
         /// 任务模式
         /// </summary>
         public string taskMode { get; set; }
+
         /// <summary>
         /// 工作位
         /// </summary>
         public string wbCode { get; set; }
+
         /// <summary>
         /// 位置路径
         /// </summary>
         public List<positionCodeClass> positionCodePath { get; set; }
+
         /// <summary>
         /// 货架编号
         /// </summary>
         public string podCode { get; set; }
+
         /// <summary>
         /// “180”,”0”,”90”,”-90”
         /// </summary>
         public string podDir { get; set; }
+
         /// <summary>
         /// 货架类型, 传空时表示随机找个货架
         /// </summary>
         public string podTyp { get; set; }
+
         /// <summary>
         /// 物料批次或货架上的物料唯一编码
         /// </summary>
         public string materialLot { get; set; }
+
         /// <summary>
         /// 优先级,从(1~127)级,最大优先级最高
         /// </summary>
         public string priority { get; set; }
+
         /// <summary>
         /// 任务单号,选填, 不填系统自动生成,UUID小于等于64位
         /// </summary>
         public string taskCode { get; set; }
+
         /// <summary>
         /// AGV编号,填写表示指定某一编号的AGV执行该任务
         /// </summary>
         public string agvCode { get; set; }
+
         /// <summary>
         /// 组编号
         /// </summary>
         public string groupId { get; set; }
+
         /// <summary>
-        /// 自定义字段.JSON格式 
+        /// 自定义字段.JSON格式
         /// </summary>
         public string data { get; set; }
     }
+
+    /// <summary>
+    ///  AGV生成任务单请求TaskTyp对应枚举
+    /// </summary>
+    public class GenAgvSchedulingTaskRequestTaskTyp
+    {
+        /// <summary>
+        ///  厂内货架搬运
+        /// </summary>
+        public string 厂内货架搬运 { get; set; } = "F01";
+
+        /// <summary>
+        ///  厂内货架空满交换
+        /// </summary>
+        public string 厂内货架空满交换 { get; set; } = "F02";
+
+        /// <summary>
+        ///  辊筒搬运接驳
+        /// </summary>
+        public string 辊筒搬运接驳 { get; set; } = "F03";
+
+        /// <summary>
+        ///  厂内货架出库AGV待命
+        /// </summary>
+        public string 厂内货架出库AGV待命 { get; set; } = "F04";
+
+        /// <summary>
+        ///  旋转货架
+        /// </summary>
+        public string 旋转货架 { get; set; } = "F05";
+
+        /// <summary>
+        ///  厂内电梯任务
+        /// </summary>
+        public string 厂内电梯任务 { get; set; } = "F06";
+
+        /// <summary>
+        ///  以下为叉车专用任务类型高位货架到工作台
+        /// </summary>
+        public string 以下为叉车专用任务类型高位货架到工作台 { get; set; } = "F11";
+
+        /// <summary>
+        ///  工作台到高位货架
+        /// </summary>
+        public string 工作台到高位货架 { get; set; } = "F12";
+
+        /// <summary>
+        ///  工作台到巷道
+        /// </summary>
+        public string 工作台到巷道 { get; set; } = "F14";
+
+        /// <summary>
+        ///  高位货架到工作台接驳
+        /// </summary>
+        public string 高位货架到工作台接驳 { get; set; } = "F15";
+
+        /// <summary>
+        ///  工作台到高位货架接驳
+        /// </summary>
+        public string 工作台到高位货架接驳 { get; set; } = "F16";
+
+        /// <summary>
+        ///  巷道到工作台接驳
+        /// </summary>
+        public string 巷道到工作台接驳 { get; set; } = "F17";
+
+        /// <summary>
+        ///  工作台到巷道接驳
+        /// </summary>
+        public string 工作台到巷道接驳 { get; set; } = "F18";
+
+        /// <summary>
+        ///  叉车电梯主任务
+        /// </summary>
+        public string 叉车电梯主任务 { get; set; } = "F20";
+    }
+
     public class positionCodeClass
     {
         public string positionCode { get; set; }

+ 25 - 0
WCS.WorkEngineering/WebApi/Models/AGV/Response/ContinueTaskResponse.cs

@@ -0,0 +1,25 @@
+namespace WCS.WorkEngineering.WebApi.Models.AGV.Response
+{
+    /// <summary>
+    ///  Agv继续执行任务返回参数
+    /// </summary>
+    public class ContinueTaskResponse
+    {
+        /// <summary>
+        ///  返回码 对应类:AgvContinueTaskResponseCode
+        /// </summary>
+        public string code { get; set; }
+
+        /// <summary>
+        ///  返回消息
+        /// </summary>
+        public string message { get; set; }
+
+        /// <summary>
+        ///  请求编号
+        /// </summary>
+        public string reqCode { get; set; }
+    }
+
+   
+}

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

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

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

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

+ 19 - 6
ServiceCenter/WebApi/Startup.cs → WCS.WorkEngineering/WebApi/Startup.cs

@@ -3,6 +3,9 @@ using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
+using Microsoft.OpenApi.Models;
+using System.Reflection;
 
 namespace ServiceCenter.WebApi
 {
@@ -19,10 +22,19 @@ namespace ServiceCenter.WebApi
         public void ConfigureServices(IServiceCollection services)
         {
             services.AddControllers();
-            //services.AddSwaggerGen(c =>
-            //{
-            //    c.SwaggerDoc("v1", new OpenApiInfo { Title = "WCSAPI", Version = "v1" });
-            //});
+            services.AddSwaggerGen(c =>
+            {
+                //c.SwaggerDoc("v1", new OpenApiInfo { Title = "WCSAPI", Version = "v1" });
+                c.SwaggerDoc("v1", new OpenApiInfo
+                {
+                    Version = "v1",
+                    Title = "WCSAPI",
+                    Description = "API描述"
+                });
+                var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
+                c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
+
+            });
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -31,8 +43,9 @@ namespace ServiceCenter.WebApi
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
-                //app.UseSwagger();
-                //app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication1 v1"));
+                app.UseSwagger();
+                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication1 v1"));
+                //http://localhost:8080/swagger/index.html
             }
 
             app.UseHttpsRedirection();

+ 20 - 2
WCS.WorkEngineering/WorkStart.cs

@@ -51,7 +51,7 @@ namespace WCS.WorkEngineering
                 {
                     var conv = new Device("BCR" + item.DeviceNo[i]);
                     conv.AddFlag(DeviceFlags.扫码);
-                    int pos = i * 14;
+                    int pos = i * 32;
                     conv.AddProtocol<IBCR80>(pos, 80, item.IP);
                     conv.AddProtocol<IBCR81>(pos, 81, item.IP);
                 }
@@ -104,6 +104,24 @@ namespace WCS.WorkEngineering
             routeInfos.Add(new RouteInfo("SRM1", new string[] { "TY1" }));
             routeInfos.Add(new RouteInfo("SRM2", new string[] { "TY2" }));
             routeInfos.Add(new RouteInfo("SRM3", new string[] { "TY3" }));
+            routeInfos.Add(new RouteInfo("TY1", new string[] { "SRM1" }));
+            routeInfos.Add(new RouteInfo("TY2", new string[] { "SRM2" }));
+            routeInfos.Add(new RouteInfo("TY3", new string[] { "SRM3" }));
+            routeInfos.Add(new RouteInfo("TY1", new string[] { "1012", "1021" }));
+            routeInfos.Add(new RouteInfo("TY2", new string[] { "1014", "1023" }));
+            routeInfos.Add(new RouteInfo("TY3", new string[] { "1016", "1025" }));
+            routeInfos.Add(new RouteInfo("1011", new string[] { "TY1" }));
+            routeInfos.Add(new RouteInfo("1022", new string[] { "TY1" }));
+            routeInfos.Add(new RouteInfo("1013", new string[] { "TY2" }));
+            routeInfos.Add(new RouteInfo("1024", new string[] { "TY2" }));
+            routeInfos.Add(new RouteInfo("1015", new string[] { "TY3" }));
+            routeInfos.Add(new RouteInfo("1026", new string[] { "TY3" }));
+
+            foreach (var item in routeInfos)
+            {
+                var device = Device.All.FirstOrDefault(x => x.Code == item.DeviceCode);
+                device.AddTarget(item.NextList);
+            }
 
             #endregion 配置路径信息
 
@@ -113,7 +131,7 @@ namespace WCS.WorkEngineering
 
             devices.Add(DeviceFlags.巷道口, new List<string>() { "1011", "1012", "1013", "1014", "1015", "1016", "1021", "1022", "1023", "1024", "1025", "1026" });
             devices.Add(DeviceFlags.入库, new List<string>() { "1011", "1013", "1015", "1022", "1024", "1026" });
-            devices.Add(DeviceFlags.出库, new List<string>() { "1012", "1014", "1016", "1021", "1023", "1025", });
+            devices.Add(DeviceFlags.出库, new List<string>() { "1012", "1014", "1016", "1021", "1023", "1025" });
 
             devices.ForEach(item =>
             {

+ 31 - 0
WCS.WorkEngineering/Worlds/DataCollectionWorld.cs

@@ -1,4 +1,6 @@
 using System.ComponentModel;
+using WCS.Core;
+using WCS.Service.Systems;
 using WCS.WorkEngineering.Worlds;
 
 namespace WCS.Service.Worlds
@@ -16,5 +18,34 @@ namespace WCS.Service.Worlds
         public DataCollectionWorld()
         {
         }
+
+        /// <summary>
+        /// 更新后执行,重写改方法后请自行添加执行内容
+        /// 执行内容:清空日志队列
+        /// </summary>
+        protected override void AfterUpdate()
+        {
+            #region 日志处理
+
+            //TODO:暂时仅将日志记录至文本文件
+            if (Logs.Count() > 0)
+            {
+                //var time = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:FF")}";
+                //var fst = Logs.First();
+                //var dir = $"Logs\\{DateTime.Now.ToString("yyyy-MM-dd")}\\{fst.Channel.World}\\{fst.Channel.System}\\";
+                //if (!Directory.Exists(dir))
+                //    Directory.CreateDirectory(dir);
+
+                //foreach (var log in Logs)
+                //{
+                //    var msg = $"--------------------{log.Time}[{Thread.CurrentThread.ManagedThreadId}]--------------------\n{log}\n";
+                //    File.AppendAllText(Path.Combine(dir, $"{log.Log.Message.Split(":")[0]}.txt"), msg);
+                //}
+            }
+
+            #endregion 日志处理
+
+            //World.GetSystemInstance<DataCollectionSysyem>().Invoke(true);
+        }
     }
 }