gkj 1 年之前
父節點
當前提交
3aa61d80b7

+ 36 - 29
ServiceCenter/Logs/LogHub.cs

@@ -17,27 +17,34 @@ namespace ServiceCenter.Logs
         {
             if (logs.Count > 0)
             {
-                //每一条数据存入redis
-                foreach (var log in logs)
+                try
                 {
-                    var dir = $"D:\\WCSLogs\\{DateTime.Now.yyyyMMdd()}\\{log.Channel.World}\\{log.Channel.System}\\{log.Channel.Item}\\";
-                    var msg = $"{log.Time.yyyyMMddhhmmssf()}--[{Thread.CurrentThread.ManagedThreadId}]--{log}\n";
-                    RedisHub.Default.RPush("LogHub", JsonConvert.SerializeObject(new LogModel
+                    //每一条数据存入redis
+                    foreach (var log in logs)
+                    {
+                        var dir = $"D:\\WCSLogs\\{DateTime.Now.yyyyMMdd()}\\{log.Channel.World}\\{log.Channel.System}\\{log.Channel.Item}\\";
+                        var msg = $"{log.Time.yyyyMMddhhmmssf()}--[{Thread.CurrentThread.ManagedThreadId}]--{log}\n";
+                        RedisHub.Default.RPush("LogHub", JsonConvert.SerializeObject(new LogModel
+                        {
+                            path = dir,
+                            Title = $"{log.Log.Message.Split(":")[0]}.txt",
+                            Con = msg
+                        }));
+                    }
+                    //存入业务报警内容
+                    List<BusinessAlarm> businesses = logs.Where(v => v.Log.Level > LogLevelEnum.Low && v.Log.LogUpLoad == LogUpLoadEnum.UpLoadWMS).Select(v => new BusinessAlarm()
                     {
-                        path = dir,
-                        Title = $"{log.Log.Message.Split(":")[0]}.txt",
-                        Con = msg
-                    }));
+                        BusinessName = v.Channel.System,
+                        DevNo = v.Channel.Item,
+                        Con = v.ToString(),
+                        Time = DateTime.Now
+                    }).ToList();
+                    RedisHub.WMS.Set($"{nameof(BusinessAlarm)}:{World}", JsonConvert.SerializeObject(businesses));
                 }
-                //存入业务报警内容
-                List<BusinessAlarm> businesses = logs.Where(v => v.Log.Level > LogLevelEnum.Low && v.Log.LogUpLoad == LogUpLoadEnum.UpLoadWMS).Select(v => new BusinessAlarm()
+                catch (Exception ex)
                 {
-                    BusinessName = v.Channel.System,
-                    DevNo = v.Channel.Item,
-                    Con = v.ToString(),
-                    Time = DateTime.Now
-                }).ToList();
-                RedisHub.WMS.Set($"{nameof(BusinessAlarm)}:{World}", JsonConvert.SerializeObject(businesses));
+                    throw;
+                }
             }
         }
 
@@ -49,12 +56,12 @@ namespace ServiceCenter.Logs
         /// <param name="msg">内容</param>
         public static async void ExRecord(this SystemBase system, string devCode, string msg)
         {
-            var key = $"{system.World.Description}:{devCode}";
-            RedisHub.Default.RPush($"{system.World.Description}:{devCode}", msg);
-            if (RedisHub.Monitor.LLen(key) > 5000)
-            {
-                RedisHub.Monitor.LTrim(key, 4000, -1);
-            }
+            //var key = $"{system.World.Description}:{devCode}";
+            //RedisHub.Default.RPush($"{system.World.Description}:{devCode}", msg);
+            //if (RedisHub.Monitor.LLen(key) > 5000)
+            //{
+            //    RedisHub.Monitor.LTrim(key, 4000, -1);
+            //}
         }
 
         /// <summary>
@@ -65,12 +72,12 @@ namespace ServiceCenter.Logs
         /// <param name="msg">内容</param>
         public static async void ExRecord<T>(this SystemBase system, string devCode, string msg, List<T> ints)
         {
-            var key = $"{system.World.Description}:{devCode}";
-            RedisHub.Default.RPush(key, msg + ints.JsonToString());
-            if (RedisHub.Monitor.LLen(key) > 5000)
-            {
-                RedisHub.Monitor.LTrim(key, 4000, -1);
-            }
+            //var key = $"{system.World.Description}:{devCode}";
+            //RedisHub.Default.RPush(key, msg + ints.JsonToString());
+            //if (RedisHub.Monitor.LLen(key) > 5000)
+            //{
+            //    RedisHub.Monitor.LTrim(key, 4000, -1);
+            //}
         }
 
         /// <summary>

+ 14 - 0
WCS.Core/DataBlock.cs

@@ -33,6 +33,20 @@ namespace WCS.Core
         {
             try
             {
+                var plc = Entity.PLCInfo.Ex();
+                if (failed)
+                {
+                    if (!plc.Ping)
+                    {
+                        if (Entity.PLCInfo.IP != "1")
+                        {
+                            Console.ForegroundColor = ConsoleColor.Red;
+                            Console.WriteLine($"{Entity.PLCInfo.IP}无法访问");
+                            Console.ResetColor();
+                        }
+                        throw new Exception($"{Entity.PLCInfo.IP}无法访问");
+                    }
+                }
 
                 Start = (ushort)ProxyList.Min(v => v.Info.Position);
                 var last = ProxyList.OrderBy(v => v.Info.Position).Last();

+ 30 - 1
WCS.Core/PLC.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.NetworkInformation;
 using System.Text;
 using System.Threading.Tasks; 
 
@@ -8,6 +9,28 @@ namespace WCS.Core
 {
     public class PLC : EntityEx<PLCInfo>
     {
+
+        public bool Ping { get; private set; }
+
+        public PLC(PLCInfo ent, World world) : base(ent)
+        {
+            if (Configs.PLCAccessorCreater != null)
+            {
+                Accessor = Configs.PLCAccessorCreater.Create(ent);
+            }
+            else
+                throw new Exception("Configs.PLCAccessorCreater未赋值");
+
+            Task.Run(() =>
+            {
+                while (true)
+                {
+                    Ping = ping();
+                    Task.Delay(1000).Wait();
+                }
+                // ReSharper disable once FunctionNeverReturns
+            });
+        }
         public PLC(PLCInfo ent) : base(ent)
         {
             if (Configs.PLCAccessorCreater != null)
@@ -19,7 +42,13 @@ namespace WCS.Core
            
         }      
         public IPLCAccessor Accessor { get; private set; }
-      
+        private bool ping(int timeout = 300)
+        {
+            var p = new Ping();
+            if (Entity.IP == "1") return false;
+            var res = p.Send(Entity.IP, timeout);
+            return res.Status == IPStatus.Success;
+        }
     }
 
     public interface IPLCAccessorCreater

+ 1 - 1
WCS.Service/Worker.cs

@@ -104,7 +104,7 @@ namespace WCS.Service
                             break;
 
                         case "WCSDlog"://WCSÈÕÖ¾Êý¾Ý¿â
-                            SqlSugarHelper.SetDefault(connectionString.Key);
+                            //SqlSugarHelper.SetDefault(connectionString.Key);
                             //_db.CodeFirst.InitTables(typeof(w));
                             //_db.CodeFirst.InitTables(typeof(WCS_TaskInfo));
                             //_db.CodeFirst.InitTables(typeof(WCS_TaskDtl));

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

@@ -30,6 +30,7 @@ namespace WCS.WorkEngineering.Extensions
         {
             if (Data.VoucherNo != Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{Data.VoucherNo}-DB521:{Data2.VoucherNo}", LogLevelEnum.High);
             if (Data3.Status.HasFlag(StatusEunm.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
+            if (!Data3.Status.HasFlag(StatusEunm.PH_Status)) throw new KnownException("无光电", LogLevelEnum.Mid);
             if (Data3.Status.HasFlag(StatusEunm.PH_Status) && Data2.Request == 0) throw new KnownException("有光电无请求", LogLevelEnum.Mid);
             if (!Data3.Status.HasFlag(StatusEunm.PH_Status) && Data2.Request == 1) throw new KnownException("无光电有请求", LogLevelEnum.Mid);
         }

+ 1 - 1
WCS.WorkEngineering/Extensions/TaskExtension.cs

@@ -96,7 +96,7 @@ namespace WCS.WorkEngineering.Extensions
                     taskOld.ManualRemarks = taskInfo.ManualRemarks;
 
                     //更新任务历史表,删除任务当前表
-                    db.Default.Updateable(taskOld).SplitTable().ExecuteCommand();
+                    db.Default.Updateable(taskOld).SplitTable(x => x.Take(2)).ExecuteCommand();
                     db.Default.Deleteable(taskInfo).ExecuteCommand();
                 }
             }

+ 141 - 60
WCS.WorkEngineering/Systems/AgvSystems.cs

@@ -1,6 +1,9 @@
-using PlcSiemens.Core.Extension;
+using Microsoft.AspNetCore.DataProtection.KeyManagement;
+using Newtonsoft.Json;
+using PlcSiemens.Core.Extension;
 using ServiceCenter.Extensions;
 using ServiceCenter.Logs;
+using ServiceCenter.Redis;
 using ServiceCenter.SqlSugars;
 using System.ComponentModel;
 using WCS.Core;
@@ -10,6 +13,7 @@ using WCS.Entity.Protocol.Station;
 using WCS.WorkEngineering.Extensions;
 using WCS.WorkEngineering.WebApi.Controllers;
 using WCS.WorkEngineering.Worlds;
+using static System.Runtime.InteropServices.JavaScript.JSType;
 using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
 
 namespace WCS.WorkEngineering.Systems
@@ -30,8 +34,10 @@ namespace WCS.WorkEngineering.Systems
 
         public AgvSystems()
         {
-            devs = Device.All.Where(v => v.HasFlag(DeviceFlags.入库, DeviceFlags.巷道口)).Select(v => new Station(v, this.World)).ToList();
-            srms = Device.All.Where(v => v.HasProtocol(typeof(ISRM520))).Select(v => new SRM(v, this.World)).ToList();
+            var stations = new List<string>() { "1011", "1012", "1013", "1014", "1015", "1016", "1021", "1022", "1023", "1024", "1025", "1026", "1117", "1118",
+                                                "1131", "1132", "1133", "1134", "1135", "1136", "1137", "1138", "1139","1127" };
+            devs = Device.All.Where(v => stations.Contains(v.Code)).Select(v => new Station(v, this.World)).ToList();
+            srms = Device.All.Where(v => v.Code is "SRM1" or "SRM2" or "SRM3" or "SRM4").Select(v => new SRM(v, this.World)).ToList();
         }
 
         public override void Do(Station obj)
@@ -51,8 +57,8 @@ namespace WCS.WorkEngineering.Systems
                 //有需要处理的AGV任务
                 if (agvTaskInfos.Any())
                 {
-                    this.ExRecord(obj.Entity.Code, "可用出库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
-                    List<WCS_TaskInfo> taskInfos = new List<WCS_TaskInfo>();
+                    //this.ExRecord(obj.Entity.Code, "可用出库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
+                    //List<WCS_TaskInfo> taskInfos = new List<WCS_TaskInfo>();
 
                     foreach (var agv in agvTaskInfos)
                     {
@@ -65,7 +71,7 @@ namespace WCS.WorkEngineering.Systems
                                 {
                                     var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
                                     agv.Status = AGVTaskStatus.Complete2;
-                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                                     taskInfo.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}在站台{agv.Station}取货");
                                     AgvApi.ContinueTask(agv.AgvID, agv.Station);
                                 }
@@ -78,19 +84,21 @@ namespace WCS.WorkEngineering.Systems
                                         if (taskInfo == null) throw new Exception($"未找到AGV任务{agv.ID}对应WCS任务");
                                         //更新AGV任务状态
                                         agv.Status = AGVTaskStatus.MissionCompleted;
-                                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                        db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                                         //更新WCS任务状态
                                         taskInfo.Status = Entity.TaskStatus.Finish;
                                         taskInfo.EedTime = DateTime.Now;
                                         db.Default.Updateable(taskInfo).ExecuteCommand();
                                         taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
+                                        //通知WMS任务完成
+                                        WmsApi.CompleteTask(taskInfo.ID);
                                         taskInfo.CompleteOrCancelTasks(db);
-                                        taskInfos.Add(taskInfo);
+                                        //taskInfos.Add(taskInfo);
                                     }
                                     else
                                     {
                                         agv.Status = AGVTaskStatus.MissionCompleted;
-                                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                        db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                                     }
                                 }
                             });
@@ -104,10 +112,10 @@ namespace WCS.WorkEngineering.Systems
                     }
 
 
-                    foreach (var item in taskInfos)
-                    {
-                        WmsApi.CompleteTask(item.ID);
-                    }
+                    //foreach (var item in taskInfos)
+                    //{
+                    //    WmsApi.CompleteTask(item.ID);
+                    //}
                 }
             }
             else if (obj.Entity.HasFlag(DeviceFlags.入库))
@@ -122,24 +130,34 @@ namespace WCS.WorkEngineering.Systems
 
                 if (agvTaskInfos.Any())
                 {
-                    this.ExRecord(obj.Entity.Code, "可用入库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
+                    //this.ExRecord(obj.Entity.Code, "可用入库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
+                    var guid = Guid.NewGuid();
+                    World.Log($"agv任务处理:开始[{guid}]", LogLevelEnum.Mid);
                     foreach (var agv in agvTaskInfos)
                     {
                         try
                         {
+                            int isApplyContainue = 0;
+                            string agvid = "";
+                            string nextpos = "";
                             SqlSugarHelper.Do(db =>
                             {
                                 //找到对应WCS任务
-                                var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
-                                if (task == null) throw new Exception($"AGV任务{agv.ID}未找到对应WCS任务");
+                                //var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
+                                //if (task == null) throw new Exception($"AGV任务{agv.ID}未找到对应WCS任务");
+                               var agvInfo = db.Default.Queryable<WCS_AgvTaskInfo>().Where(x => x.ID == agv.ID).SplitTable(s => s.Take(3)).First();
                                 #region 开始跟据AGV状态做出处理
                                 //巷道分配
-                                if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission1 && agv.Status != AGVTaskStatus.Complete1)
+                                if (agvInfo.AgvStatus == AGVTaskStatus.RequestOrPermission1 && agvInfo.Status != AGVTaskStatus.Complete1)
                                 {
-                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agv.ID}开始进行巷道分配");
+
+                                    //找到对应WCS任务
+                                    var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvInfo.ID);
+                                    if (task == null) throw new Exception($"AGV任务{agvInfo.ID}未找到对应WCS任务");
+                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID}开始进行巷道分配");
                                     //向WMS获取巷道优先级'
                                     var res = WmsApi.GetTunnelPriorityList(task.ID);
-                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agv.ID},WMS返回巷道优先级{res.ResData}");
+                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},WMS返回巷道优先级{res.ResData}");
                                     var tunnelNo = res.ResData.Split(",").Select(v => "SRM" + v).ToList();
 
                                     //开始获取堆垛机与可用站台信息
@@ -147,13 +165,23 @@ namespace WCS.WorkEngineering.Systems
                                     List<Station> stations = new List<Station>();
                                     if (task.Floor == 1) //一楼
                                     {
-                                        //一楼三个入库口
-                                        stations = devs.Where(v => v.Entity.Code is "1011" or "1013" or "1015").ToList();
+                                        //一楼三个入库口 新增一个巷道,两个入库口
+                                        stations = devs.Where(v => v.Entity.Code is "1011" or "1013" or "1015" or "1117" or "1138").ToList();
+
+                                        //过滤有任务的站台
+                                        var taskinstations = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.TaskType == AGVTaskType.EnterDepot && v.Status < AGVTaskStatus.MissionCompleted && (v.Position == "1011" || v.Position == "1013" || v.Position == "1015" || v.Position == "1117" || v.Position == "1138")).SplitTable(v => v.Take(2)).Select(v => v.Position).ToList();
+                                        stations = stations.Where(p => !taskinstations.Contains(p.Entity.Code)).ToList();
+
                                         //筛选出可用站台
                                         stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StatusEunm.Auto))
                                                            .Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.OT_Status))
                                                            .Where(v => !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList(); // 筛选出可用站台
-                                        this.ExRecord(obj.Entity.Code, $"AGV任务{agv.ID},可用放货站台", stations.Select(v => v.Entity.Code).ToList());
+
+                                        //var putS = stations.Select(v => v.Entity.Code);
+                                        var dev = devs.Find(v => v.Entity.Code == "1138");
+                                        World.Log($"放货站台1138信号凭证号{dev.Data.VoucherNo}-{dev.Data2.VoucherNo}-自动{dev.Data3.Status.HasFlag(StatusEunm.Auto)}-光电{dev.Data3.Status.HasFlag(StatusEunm.PH_Status)}-有货光电{dev.Data3.Status.HasFlag(StatusEunm.OT_Status)}-{dev.Data3.Status.HasFlag(StatusEunm.Run)}");
+                                        //World.Log($"可用放货站台{JsonConvert.SerializeObject(putS)}");
+                                        this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},可用放货站台", stations.Select(v => v.Entity.Code).ToList());
                                         //可用堆垛机
                                         srm = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()) //上一个地址是巷道的
                                                       .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
@@ -161,16 +189,28 @@ namespace WCS.WorkEngineering.Systems
                                                       .Where(v => v != null && !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic) //筛选出可用堆垛机
                                                       .Where(v => tunnelNo.Contains(v.Entity.Code)) //筛选出巷道优先级最高的堆垛机
                                                       .MinBy(v => tunnelNo.IndexOf(v.Entity.Code));//按照巷道优先级排序
+
+                                     
                                     }
                                     else //二楼
                                     {
-                                        //二楼三个入库口
-                                        stations = devs.Where(v => v.Entity.Code is "1021" or "1023" or "1025").ToList();
+                                        //二楼三个入库口 新增一个巷道,1个入库口
+                                        stations = devs.Where(v => v.Entity.Code is "1021" or "1023" or "1025" or "1127").ToList();
+                                        //过滤有任务的站台
+                                        var taskinstations = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.TaskType == AGVTaskType.EnterDepot && v.Status < AGVTaskStatus.MissionCompleted && (v.Position == "1021" || v.Position == "1023" || v.Position == "1025" || v.Position == "1127")).SplitTable(v => v.Take(2)).Select(v => v.Position).ToList();
+                                        stations = stations.Where(p => !taskinstations.Contains(p.Entity.Code)).ToList();
+
                                         //筛选出可用站台
                                         stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StatusEunm.Auto))
                                                            .Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.OT_Status))
                                                            .Where(v => !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList(); // 筛选出可用站台
-                                        this.ExRecord(obj.Entity.Code, $"AGV任务{agv.ID},可用放货站台", stations.Select(v => v.Entity.Code).ToList());
+                                        //var putS1 = stations.Select(v => v.Entity.Code);
+                                        var dev = devs.Find(v => v.Entity.Code == "1127");
+                                        World.Log($"放货站台1127信号凭证号{dev.Data.VoucherNo}-{dev.Data2.VoucherNo}-自动{dev.Data3.Status.HasFlag(StatusEunm.Auto)}-光电{dev.Data3.Status.HasFlag(StatusEunm.PH_Status)}-有货光电{dev.Data3.Status.HasFlag(StatusEunm.OT_Status)}-{dev.Data3.Status.HasFlag(StatusEunm.Run)}");
+
+
+
+                                        this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},可用放货站台", stations.Select(v => v.Entity.Code).ToList());
                                         //可用堆垛机
                                         srm = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()) //上一个地址是巷道的
                                                       .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
@@ -180,20 +220,20 @@ namespace WCS.WorkEngineering.Systems
                                                       .MinBy(v => tunnelNo.IndexOf(v.Entity.Code));//按照巷道优先级排序
 
                                     }
-                                    if (srm == null) throw new Exception($"agv任务{agv.ID}无可用堆垛机");
+                                    if (srm == null) throw new Exception($"agv任务{agvInfo.ID}无可用堆垛机");
 
                                     //筛选出堆垛机的放货站台
                                     var nextPos = stations.FirstOrDefault(v => v.Entity.Sources.Where(t => t.IsTunnel()).Select(t => t.Sources).SelectMany(v => v) //获取所有巷道
                                                                                                .Where(t => t.HasProtocol(typeof(ISRM520)))//筛选出堆垛机
                                                                                                .SelectMany(v => v.Sources).Any(t => t.Code == srm.Entity.Parent.Code));
-                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agv.ID},放货站台{nextPos}");
+                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},放货站台{nextPos}");
 
                                     bool flag = false;
-                                    if (((task.BusType == "二楼湿拉线退料回立库" || task.BusType == "二楼湿拉线余料回立库") && task.Floor == 2))
-                                    {
-                                        flag = true;
-                                        nextPos.Entity.Code = "1025";
-                                    }
+                                    //if (((task.BusType == "二楼湿拉线退料回立库" || task.BusType == "二楼湿拉线余料回立库") && task.Floor == 2))
+                                    //{
+                                    //    flag = true;
+                                    //    nextPos.Entity.Code = "1025";
+                                    //}
                                     var agvs = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.Position == nextPos.Entity.Code).SplitTable(v => v.Take(2)).ToList();
                                     if (agvs.Any())
                                     {
@@ -204,59 +244,99 @@ namespace WCS.WorkEngineering.Systems
                                         }
                                         throw new Exception(msg);
                                     }
+                                    //wcs任务状态卡控,防止因光电异常误判                                   
+                                    if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrNext == nextPos.Entity.Code && v.Status == Entity.TaskStatus.ConveyorExecution)) return;
+
+
+                                    if (RedisHub.Default.Get("TaskTun:" + task.ID) != null && RedisHub.Default.Get("TaskTun:" + task.ID) != nextPos.Entity.Code)
+                                    {
+                                        throw new Exception("WCS任务:" + task.ID + "已经分配过巷道,不允许重新分配不同巷道");
+                                    }
+
 
-                                                                       
                                     //更新AGV任务状态
-                                    agv.Status = AGVTaskStatus.Complete1;
-                                    agv.Position = flag == true ? "1025" : nextPos.Entity.Code;
-                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    agvInfo.Status = AGVTaskStatus.Complete1;
+                                    //agv.Position = flag == true ? "1025" : nextPos.Entity.Code;
+                                    agvInfo.Position = nextPos.Entity.Code;
+                                    var upres1 = db.Default.Updateable(agvInfo).SplitTable(x => x.Take(2)).ExecuteCommand();
                                     //更新WCS任务状态
-                                    if (flag)
+                                    //if (flag)
+                                    //{
+                                    //    srm.Entity.Code = "SRM3";
+                                    //    task.Device = srm.Entity.Code;
+                                    //    task.Tunnel = "3";
+                                    //    task.AddrNext = "1025";
+                                    //    task.SrmStation = "1025";
+                                    //}
+                                    //else
                                     {
-                                        srm.Entity.Code = "SRM3";
-                                        task.Device = srm.Entity.Code;
-                                        task.Tunnel = "3";
-                                        task.AddrNext = "1025";
-                                    }
-                                    else {
                                         task.Device = srm.Entity.Code;
                                         task.Tunnel = task.Device.GetLastDigit().ToString();
-                                        task.AddrNext = agv.Position;
-                                    }                                   
-                                    db.Default.Updateable(task).ExecuteCommand();                                    
+                                        task.AddrNext = agvInfo.Position;
+                                        task.SrmStation = nextPos.Entity.Code;
+                                    }
+                                    var upres =  db.Default.Updateable(task).ExecuteCommand();
                                     task.AddWCS_TASK_DTL(db, "AGV巷道分配点", nextPos.Entity.Code, $"任务分配至堆垛机:{srm.Entity.Code}");
-                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agv.ID}分配至堆垛机:{srm.Entity.Code}");
-                                    //调继续执行任务接口
-                                    AgvApi.ContinueTask(agv.AgvID, nextPos.Entity.Code);
+                                    this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID}分配至堆垛机:{srm.Entity.Code}");
+
+
+                                    if (upres > 0 && upres1 > 0)
+                                    {
+                                        //调继续执行任务接口(监控发现海康接口有不响应的情况,会导致事务不执行,把接口调用拿到事务外面)
+                                        //AgvApi.ContinueTask(agvInfo.AgvID, nextPos.Entity.Code);
+                                        isApplyContainue = 1;
+                                        agvid = agvInfo.AgvID;
+                                        nextpos = nextPos.Entity.Code;
+                                        RedisHub.Default.Set("TaskTun:" + task.ID, nextPos.Entity.Code, 600);
+                                    }
+
                                 }
                                 //放货站点安全交互
-                                else if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
+                                else if (agvInfo.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agvInfo.Status != AGVTaskStatus.Complete2)
                                 {
-                                    if (agv.Position.IsNullOrEmpty()) throw new Exception($"无有效放货地址");
-                                    var dev = devs.Find(v => v.Entity.Code == agv.Position);
+                                    //找到对应WCS任务
+                                    var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvInfo.ID);
+                                    if (task == null) throw new Exception($"AGV任务{agvInfo.ID}未找到对应WCS任务");
+
+                                    if (agvInfo.Position.IsNullOrEmpty()) throw new Exception($"无有效放货地址");
+
+                                    if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrNext == agvInfo.Position && v.Status == Entity.TaskStatus.ConveyorExecution)) throw new Exception($"AGV请求放货,但{agvInfo.Position}上任务状态异常"); ;
+                                    var dev = devs.Find(v => v.Entity.Code == agvInfo.Position);
 
                                     if (dev.Data.VoucherNo != dev.Data2.VoucherNo) throw new Exception($"AGV请求放货,但{dev.Entity.Code}凭证号不一致");
                                     if (!dev.Data3.Status.HasFlag(StatusEunm.Auto)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}不在自动状态");
                                     if (dev.Data3.Status.HasFlag(StatusEunm.PH_Status)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}光电有货");
                                     if (dev.Data3.Status.HasFlag(StatusEunm.OT_Status)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}任务有货");
                                     if (dev.Data3.Status.HasFlag(StatusEunm.Run)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}在运行状态");
-                                    agv.Status = AGVTaskStatus.Complete2;
-                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
-
-                                    //调继续执行任务接口
-                                    AgvApi.ContinueTask(agv.AgvID, dev.Entity.Code);
+                                    agvInfo.Status = AGVTaskStatus.Complete2;
+                                    db.Default.Updateable(agvInfo).SplitTable(x => x.Take(2)).ExecuteCommand();
 
                                     dev.Data.TaskNumber = task.ID;
+                                    World.Log($"agvRequestOrPermission2:taskid[{dev.Data.TaskNumber}]", LogLevelEnum.Mid);
+                                    //调继续执行任务接口
+                                    AgvApi.ContinueTask(agvInfo.AgvID, dev.Entity.Code);
                                 }
                                 //完成任务
-                                else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
+                                else if (agvInfo.AgvStatus == AGVTaskStatus.MissionCompleted && agvInfo.Status != AGVTaskStatus.MissionCompleted)
                                 {
-                                    agv.Status = AGVTaskStatus.MissionCompleted;
-                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    agvInfo.Status = AGVTaskStatus.MissionCompleted;
+                                    db.Default.Updateable(agvInfo).SplitTable(x => x.Take(2)).ExecuteCommand();
                                 }
 
                                 #endregion 开始跟据AGV状态做出处理
                             });
+                            if (isApplyContainue > 0)
+                            {
+                                SqlSugarHelper.Do(db =>
+                                {
+                                    var agvInfo = db.Default.Queryable<WCS_AgvTaskInfo>().Where(x => x.AgvID == agvid).SplitTable(s => s.Take(2)).First();
+                                    if (agvInfo.Status == AGVTaskStatus.Complete1)
+                                    {
+                                        AgvApi.ContinueTask(agvid, nextpos);
+                                    }
+                                });
+                                //AgvApi.ContinueTask(agvid, nextpos);
+                            }
                         }
                         catch (Exception ex)
                         {
@@ -265,6 +345,7 @@ namespace WCS.WorkEngineering.Systems
                             continue;
                         }
                     }
+                    World.Log($"agv任务处理:结束[{guid}]", LogLevelEnum.Mid);
                 }
             }
         }

+ 10 - 10
WCS.WorkEngineering/Systems/DataCollectionSysyem.cs

@@ -86,7 +86,7 @@ namespace WCS.Service.Systems
                 //保存模式
                 var status = ConvList.Select(v => new Tuple<string, string>(v.Entity.Code, v.Data2.Mode.ToString()));
                 RedisHub.WMS.Set($"ConvStatus", JsonConvert.SerializeObject(status));
-                pack.StationDatas = new DeviceDataCollection<StationData>(DateTime.Now, DevList.ToArray());
+                //pack.StationDatas = new DeviceDataCollection<StationData>(DateTime.Now, DevList.ToArray());
 
                 //处理堆垛机
                 List<SRMData> srmList = new List<SRMData>();
@@ -113,16 +113,16 @@ namespace WCS.Service.Systems
                 //保存模式
                 var status1 = Srms.Select(v => new Tuple<string, string>(v.Entity.Code, v.Data2.AutoStatus.ToString()));
                 RedisHub.WMS.Set($"SrmStatus", JsonConvert.SerializeObject(status1));
-                pack.SRMDatas = new DeviceDataCollection<SRMData>(DateTime.Now, srmList.ToArray());
-                pack.Frame = DateTime.Now;
+                //pack.SRMDatas = new DeviceDataCollection<SRMData>(DateTime.Now, srmList.ToArray());
+                //pack.Frame = DateTime.Now;
 
-                //保存到Redis
-                RedisHub.Monitor.RPush("Packs", pack);
-                RedisHub.Monitor.Set(nameof(DeviceDataPack), pack);
-                if (RedisHub.Monitor.LLen("Packs") > 500000)
-                {
-                    RedisHub.Monitor.LTrim("Packs", 5000, -1);
-                }
+                ////保存到Redis
+                //RedisHub.Monitor.RPush("Packs", pack);
+                //RedisHub.Monitor.Set(nameof(DeviceDataPack), pack);
+                //if (RedisHub.Monitor.LLen("Packs") > 500000)
+                //{
+                //    RedisHub.Monitor.LTrim("Packs", 5000, -1);
+                //}
             }
             catch (Exception ex)
             {

+ 44 - 7
WCS.WorkEngineering/Systems/NoInteractionSystems.cs

@@ -71,7 +71,8 @@ namespace WCS.WorkEngineering.Systems
                                         };
                                         if (task.Floor == 2)
                                         {
-                                            task.Tunnel = "3";
+                                            //task.Tunnel = "3";
+                                            task.Tunnel = "";
                                             task.Device = "SRM3";
                                             task.SrmStation = "1025";
                                         }
@@ -100,6 +101,37 @@ namespace WCS.WorkEngineering.Systems
                                             db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
                                             task.AgvTaskID = agvTask.ID;
                                         }
+                                        else if (task.Floor == 1 && task.BusType == "一楼出满轮")
+                                        {
+                                            //创建AGV任务
+                                            var agvTask = new WCS_AgvTaskInfo()
+                                            {
+                                                ID = db.GetAGVTaskId(),
+                                                TaskType = AGVTaskType.CallMaterial,
+                                                Status = AGVTaskStatus.NewBuild,
+                                                Station = task.SrmStation,
+                                                Position = task.AddrTo,
+                                                WorkShop = 111,
+                                                AddWho = "WCS"
+                                            };
+                                            db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                                            task.AgvTaskID = agvTask.ID;
+                                        }
+                                        else if (task.BusType == "一楼立库出空轮")
+                                        {
+                                            //创建AGV任务
+                                            var agvTask = new WCS_AgvTaskInfo()
+                                            {
+                                                ID = db.GetAGVTaskId(),
+                                                TaskType = AGVTaskType.CallForMaterial,
+                                                Status = AGVTaskStatus.NewBuild,
+                                                Station = task.SrmStation,
+                                                Position = task.AddrTo,
+                                                AddWho = "WCS"
+                                            };
+                                            db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                                            task.AgvTaskID = agvTask.ID;
+                                        }
 
                                         #endregion 二楼非半自动手动出库任务需要创建AGV任务
 
@@ -172,24 +204,29 @@ namespace WCS.WorkEngineering.Systems
                         {
                             SqlSugarHelper.Do(db =>
                             {
+                                string barCode = "";
                                 var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(t => t.ID == item.ID).SplitTable(v => v.Take(2)).First() ?? throw new Exception($"未找到对应的AGV任务:{item.ID}");
                                 //获取对应wcs任务
-                                var wcs = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.AgvTaskID == agv.ID && t.Status == Entity.TaskStatus.WaitingToExecute).First() ?? throw new Exception($"AGV任务[{item.ID}]未找到对应的WCS任务");
-
+                                var wcs = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.AgvTaskID == agv.ID && t.Status == Entity.TaskStatus.WaitingToExecute).First() ?? throw new Exception($"AGV任务[{item.ID}]未找到对应的WCS任务");                               
                                 switch (wcs.Floor)
                                 {
                                     case 1: //一楼下发AGV任务
                                         var res = AgvApi.满轮入库(wcs.BarCode, agv.Station, Guid.NewGuid().ToString().Replace("-", ""), "1");
                                         agv.Status = AGVTaskStatus.Confirm;
                                         agv.AgvID = res.data;
-                                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                        db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                                         break;
 
                                     case 2:
-                                        var agvRes = IwmsApi.空轮回库(wcs.MatCode, wcs.SrmStation, wcs.IsSurplus, wcs.IsRework, agv.ID, wcs.BarCode);
+                                        barCode = wcs.BarCode;
+                                        if (!string.IsNullOrEmpty(wcs.BarCode) && wcs.BarCode.Contains("-"))
+                                        {
+                                            barCode = wcs.BarCode.Substring(0, wcs.BarCode.IndexOf("-"));
+                                        }                                       
+                                        var agvRes = IwmsApi.空轮回库(wcs.MatCode, wcs.SrmStation, wcs.IsSurplus, wcs.IsRework, agv.ID, barCode, wcs.AddWho);
                                         agv.Status = AGVTaskStatus.Confirm;
                                         agv.AgvID = agvRes.data;
-                                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                        db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                                         break;
 
                                     default:
@@ -238,7 +275,7 @@ namespace WCS.WorkEngineering.Systems
                                 res = AgvApi.机台补空(agv.Station, Guid.NewGuid().ToString().Replace("-", ""), "1");
                                 agv.Status = AGVTaskStatus.Confirm;
                                 agv.AgvID = res.data;
-                                db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
 
                                 wcs.Status = Entity.TaskStatus.AGVExecution;
                                 db.Default.Updateable(wcs).ExecuteCommand();

+ 409 - 206
WCS.WorkEngineering/Systems/SrmSystems.cs

@@ -3,6 +3,7 @@ using ServiceCenter.Extensions;
 using ServiceCenter.Logs;
 using ServiceCenter.SqlSugars;
 using System.ComponentModel;
+using System.Threading.Tasks;
 using WCS.Core;
 using WCS.Entity;
 using WCS.Entity.Protocol.SRM;
@@ -94,11 +95,35 @@ namespace WCS.WorkEngineering.Systems
                     switch (task.Type)
                     {
                         case TaskType.EnterDepot:
-                            //完成任务
-                            task.Status = Entity.TaskStatus.Finish;
-                            task.EedTime = DateTime.Now;
-                            db.Default.Updateable(task).ExecuteCommand();
-                            task.AddWCS_TASK_DTL(db, task.AddrTo, "入库任务结束");
+                            if (task.TaskGroupKey == "1")
+                            {
+                                //完成任务
+                                task.Status = Entity.TaskStatus.ConveyorExecution;
+                                var dev = new Station(Device.All.FirstOrDefault(v => v.Code == task.AddrTo), this.World);
+                                dev.Data.TaskNumber = task.ID;
+                                task.EedTime = DateTime.Now;
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, task.AddrTo, "二楼搬运空轮至一楼任务到达放货站台,堆垛机完成");
+                            }
+                            else if (task.ProdLine == 1)
+                            {
+                                //完成任务
+                                task.Status = Entity.TaskStatus.ConveyorExecution;
+                                var dev = new Station(Device.All.FirstOrDefault(v => v.Code == task.AddrTo), this.World);
+                                dev.Data.TaskNumber = task.ID;
+                                task.EedTime = DateTime.Now;
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, task.AddrTo, "一楼搬运满轮至二楼任务到达放货站台,堆垛机完成");
+                            }
+                            else
+                            {
+                                //完成任务
+                                task.Status = Entity.TaskStatus.Finish;
+                                task.EedTime = DateTime.Now;
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, task.AddrTo, "入库任务结束,堆垛机完成");
+                            }
+                          
                             break;
 
                         case TaskType.OutDepot:
@@ -109,7 +134,7 @@ namespace WCS.WorkEngineering.Systems
                                     var dev = new Station(Device.All.FirstOrDefault(v => v.Code == task.SrmStation), this.World);
                                     dev.Data.TaskNumber = task.ID;
                                     db.Default.Updateable(task).ExecuteCommand();
-                                    task.AddWCS_TASK_DTL(db, task.SrmStation, "出库任务到达放货站台");
+                                    task.AddWCS_TASK_DTL(db, task.SrmStation, "出库任务到达放货站台,堆垛机完成");
                                     break;
 
                                 case OutTypeEnum.全自动手动出库任务:
@@ -120,7 +145,7 @@ namespace WCS.WorkEngineering.Systems
                                     task.Status = Entity.TaskStatus.Finish;
                                     task.EditTime = DateTime.Now;
                                     db.Default.Updateable(task).ExecuteCommand();
-                                    task.AddWCS_TASK_DTL(db, task.SrmStation, "半自动手动出库任务结束");
+                                    task.AddWCS_TASK_DTL(db, task.SrmStation, "半自动手动出库任务结束,堆垛机完成");
                                     break;
 
                                 default:
@@ -133,17 +158,21 @@ namespace WCS.WorkEngineering.Systems
                             task.Status = Entity.TaskStatus.Finish;
                             task.EedTime = DateTime.Now;
                             db.Default.Updateable(task).ExecuteCommand();
-                            task.AddWCS_TASK_DTL(db, task.AddrTo, "移库任务结束");
+                            task.AddWCS_TASK_DTL(db, task.AddrTo, "移库任务结束,堆垛机完成");
                             break;
 
                         case TaskType.EmptyInit:
                             task.Status = Entity.TaskStatus.Finish;
                             task.EedTime = DateTime.Now;
                             db.Default.Updateable(task).ExecuteCommand();
-                            task.AddWCS_TASK_DTL(db, task.AddrTo, "空轮初始化任务结束");
+                            task.AddWCS_TASK_DTL(db, task.AddrTo, "空轮初始化任务结束,堆垛机完成");
                             break;
                     }
 
+                    //通知WMS任务完成
+                    if (task.Status == TaskStatus.Finish) WmsApi.CompleteTask(task.ID);
+                    if (task.Type == TaskType.OutDepot && task.Status == TaskStatus.ConveyorExecution) WmsApi.SrmPickOutCompleted(task.ID);
+
                     if (task.Status >= TaskStatus.Finish) task.CompleteOrCancelTasks(db);
 
                     taskInfo = task;
@@ -152,10 +181,11 @@ namespace WCS.WorkEngineering.Systems
                 // 写入信号
                 obj.Data.OkAck = 1;
                 //通知WMS任务完成
-                if (taskInfo.Status == TaskStatus.Finish) WmsApi.CompleteTask(taskInfo.ID);
-                if (taskInfo.Type == TaskType.OutDepot && taskInfo.Status == TaskStatus.ConveyorExecution) WmsApi.SrmPickOutCompleted(taskInfo.ID);
+                //if (taskInfo.Status == TaskStatus.Finish) WmsApi.CompleteTask(taskInfo.ID);
+                //if (taskInfo.Type == TaskType.OutDepot && taskInfo.Status == TaskStatus.ConveyorExecution) WmsApi.SrmPickOutCompleted(taskInfo.ID);
+
+
 
-                World.Log($"堆垛机任务处理:结束--完成任务{obj.Data2.TaskFinishiId}", LogLevelEnum.Mid);
             }
 
             #endregion 处理完成任务
@@ -199,226 +229,399 @@ namespace WCS.WorkEngineering.Systems
                     }
                 }
 
-                ////判断是否存在调整优先级任务
-                //if (!tasks.Any(v => v.Type != TaskType.TransferDepot && v.Status < Entity.TaskStatus.StackerExecution && v.Priority > 0))
-                //{
-                //    //不存在调整优先级任务,判断是否存在移库任务
-                //    isTransfer = tasks.Any(v => v.Type == TaskType.TransferDepot && v.Status == Entity.TaskStatus.NewBuild);
-                //}
-                //else //存在调整优先级任务
-                //{
-                //    //获取出库任务中新建状态最大优先级
-                //    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).Max(v => v.Priority);
-                //    //出入库最大优先级相加大于零
-                //    if (outPriorityNewBuild + enterPriority > 0)
-                //    {
-                //        //出入库优先级任务 1:无优先 2:入库 3:出库
-                //        enterOrOut = enterPriority > outPriorityNewBuild ? 2 : 3;
-                //    }
-                //}
-            });
+                #region 移库
 
-            #region 移库
+                if (isTransfer)
+                {
+                    WCS_TaskInfo taskInfo = null;
+                    SqlSugarHelper.Do(db =>
+                    {
+                        //获取一条当前堆垛机优先级最高的新建移库任务
+                        var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Device == obj.Entity.Code && v.Type == TaskType.TransferDepot && v.Status == Entity.TaskStatus.NewBuild)
+                                                                       .OrderByDescending(v => v.Priority)
+                                                                       .First() ?? throw new KnownException("未找到移库任务", LogLevelEnum.High);
+                        //任务状态改为堆垛机执行中
+                        task.Status = Entity.TaskStatus.StackerExecution;
+                        task.StartTime = DateTime.Now;
+                        db.Default.Updateable(task).ExecuteCommand();
+                        task.AddWCS_TASK_DTL(db, task.AddrFrom, task.Device, $"堆垛机{obj.Entity.Code}开始执行任务");
+                        taskInfo = task;
+                    });
+                    if (taskInfo == null) throw new KnownException("数据更新错误", LogLevelEnum.High);
+                    var addrFrom = taskInfo.AddrFrom.Split("-");
+                    var addrTo = taskInfo.AddrTo.Split("-");
+                    World.Log($"堆垛机任务处理:开始--下发移库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                    //下发任务
+                    obj.Data.TaskNumber = taskInfo.ID;
+                    obj.Data.SLine = addrFrom[0].ToShort();
+                    obj.Data.SCol = addrFrom[1].ToShort();
+                    obj.Data.SLayer = addrFrom[2].ToShort();
+                    obj.Data.ELine = addrTo[0].ToShort();
+                    obj.Data.ECol = addrTo[1].ToShort();
+                    obj.Data.ELayer = addrTo[2].ToShort();
+                    obj.Data.TaskType = SrmTaskTypeEnum.MoveGoods;
+                    obj.Data.VoucherNo++;
+                    World.Log($"堆垛机任务处理:结束---下发移库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                }
 
-            if (isTransfer)
-            {
-                WCS_TaskInfo taskInfo = null;
-                SqlSugarHelper.Do(db =>
-                   {
-                       //获取一条当前堆垛机优先级最高的新建移库任务
-                       var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Device == obj.Entity.Code && v.Type == TaskType.TransferDepot && v.Status == Entity.TaskStatus.NewBuild)
-                                                                      .OrderByDescending(v => v.Priority)
-                                                                      .First() ?? throw new KnownException("未找到移库任务", LogLevelEnum.High);
-                       //任务状态改为堆垛机执行中
-                       task.Status = Entity.TaskStatus.StackerExecution;
-                       task.StartTime = DateTime.Now;
-                       db.Default.Updateable(task).ExecuteCommand();
-                       task.AddWCS_TASK_DTL(db, task.AddrFrom, task.Device, $"堆垛机{obj.Entity.Code}开始执行任务");
-                       taskInfo = task;
-                   });
-                if (taskInfo == null) throw new KnownException("数据更新错误", LogLevelEnum.High);
-                var addrFrom = taskInfo.AddrFrom.Split("-");
-                var addrTo = taskInfo.AddrTo.Split("-");
-                World.Log($"堆垛机任务处理:开始--下发移库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
-                //下发任务
-                obj.Data.TaskNumber = taskInfo.ID;
-                obj.Data.SLine = addrFrom[0].ToShort();
-                obj.Data.SCol = addrFrom[1].ToShort();
-                obj.Data.SLayer = addrFrom[2].ToShort();
-                obj.Data.ELine = addrTo[0].ToShort();
-                obj.Data.ECol = addrTo[1].ToShort();
-                obj.Data.ELayer = addrTo[2].ToShort();
-                obj.Data.TaskType = SrmTaskTypeEnum.MoveGoods;
-                obj.Data.VoucherNo++;
-                World.Log($"堆垛机任务处理:结束---下发移库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
-            }
+                #endregion 移库
 
-            #endregion 移
+                #region 出入库
 
-            #region 出入库
+                //上一个周期是不是出库任务 第一次获取返回结果会是false
+                var lastIsOut = obj.Entity.GetFlag<bool>("LastIsOut");
+                obj.Entity.SetFlag("LastIsOut", !lastIsOut);
 
-            //上一个周期是不是出库任务 第一次获取返回结果会是false
-            var lastIsOut = obj.Entity.GetFlag<bool>("LastIsOut");
-            obj.Entity.SetFlag("LastIsOut", !lastIsOut);
+                //入库任务优先 或 上一个周期是出库任务并且出库任务无优先
+                if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
+                {
+                    //判断本次优先执行楼层,并设置下次执行时优先楼层
+                    var floor = obj.Entity.GetFlag<int>("FloorIn");
+                    floor = floor % 2 + 1;
+                    obj.Entity.SetFlag("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.Data.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.Low);
+                    WCS_TaskInfo taskInfo = null;
+                    Station station = null;
+                    //判断1楼空轮位是否满足直接放下去的条件
+                    #region 二楼空轮搬运直接去一楼
+
+                    bool isDirToStation = true;
+                    string tostation = "";
+                    #endregion
+                    SqlSugarHelper.Do(db =>
+                    {
+                        //根据有货设备的任务号获取所有类型为入库状态为输送机执行中的任务
+                        var tasks = db.Default.Queryable<WCS_TaskInfo>().Where(v => (v.Type == TaskType.EnterDepot || v.Type == TaskType.EmptyInit)
+                                                                                  && v.Status == TaskStatus.ConveyorExecution
+                                                                                  && arrIn.Select(p => p.Data.TaskNumber).Contains(v.ID) && v.Device == obj.Entity.Code);
+                        //按条件先后排序获取一条排序后第一条结果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);
+                        if (task.BusType == "二楼湿拉空轮回立库")
+                        {
+                            var arrOut = PutDevices.First(v => v.Key == obj.Entity.Code).Value;
+
+                            if (!arrOut.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无放货路径点", LogLevelEnum.High);
+                            var list = new List<string>() { "1012", "1014", "1016", "1118", "1131", "1132", "1133", "1134", "1135", "1136", "1137", "1139" };
+                            //获取可以放货的设备集合
+                            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) //未分配任务
+                                                            && list.Contains(v.Entity.Code)
+                                                            && v.Data3.Status.HasFlag(StatusEunm.Auto)).ToList(); //自动
+
+                            if (!arrOut.Any()) { isDirToStation = false; };
+
+                            if (isDirToStation == true)
+                            {
+                                var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();//一楼的出库站台
+                                tostation = allOutCode.First();
+
+                                var taskout = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.StackerExecution && v.Device == obj.Entity.Code)
+                                                                                .Where(v => allOutCode.Contains(v.SrmStation))
+                                                                                .First();
+                                if (taskout != null) { isDirToStation = false; };
+
+                                if (isDirToStation == true)
+                                {
+                                    if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrTo == tostation && v.Status == TaskStatus.ConveyorExecution)) { isDirToStation = false; };
+                                }
+                                if (isDirToStation == true)
+                                {
+                                    //判断是否有小于agv小车离开取货位状态的agv任务,有的话则不允许下发
+                                    if (db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Station == tostation && v.AgvStatus < AGVTaskStatus.Complete3 && v.AgvStatus >= AGVTaskStatus.RequestOrPermission2).SplitTable(tabs => tabs.Take(2)).Any())
+                                    {
+                                        isDirToStation = false;
+                                    }
+                                }
+                            }
 
-            //入库任务优先 或 上一个周期是出库任务并且出库任务无优先
-            if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
-            {
-                //判断本次优先执行楼层,并设置下次执行时优先楼层
-                var floor = obj.Entity.GetFlag<int>("FloorIn");
-                floor = floor % 2 + 1;
-                obj.Entity.SetFlag("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.Data.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;
-                SqlSugarHelper.Do(db =>
+                            //获取任务所有设备
+                            station = arrIn.First(v => v.Data.TaskNumber == task.ID);
+                            if (isDirToStation)
+                            {
+                                task.Status = TaskStatus.StackerExecution;
+                                task.AddrTo = tostation;
+                                task.LastInteractionPoint = station.Entity.Code;
+                                task.AddrNext = tostation;
+                                task.EditWho = "WCS";
+                                task.TaskGroupKey = "1";
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行,去一楼出库点");
+                                taskInfo = task;
+                            }
+                            else//空轮子入库
+                            {
+                                //获取任务所有设备
+                                station = arrIn.First(v => v.Data.TaskNumber == task.ID);
+                                //获取当前货物巷道
+                                var res = WmsApi.GetLocalIn(task.ID, task.Device, station.Entity.Code);
+                                var loc = res.ResData.CellNo.Split("-");
+                                task.Status = TaskStatus.StackerExecution;
+                                task.AddrTo = $"{loc[0]}-{loc[1]}-{loc[2]}";
+                                task.LastInteractionPoint = station.Entity.Code;
+                                task.EditWho = "WCS";
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行");
+                                taskInfo = task;
+                            }
+                        }
+                        else if (task.BusType == "镀铜一楼取满" && task.ProdLine == 1)//满轮越库
+                        {
+                            var arrOut = PutDevices.First(v => v.Key == obj.Entity.Code).Value;
+
+                            if (!arrOut.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无放货路径点", LogLevelEnum.High);
+                            var list = new List<string>() { "1022", "1024", "1026", "1128"};
+                            //获取可以放货的设备集合
+                            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) //未分配任务
+                                                            && list.Contains(v.Entity.Code)
+                                                            && v.Data3.Status.HasFlag(StatusEunm.Auto)).ToList(); //自动
+
+                            if (!arrOut.Any()) { isDirToStation = false; };
+
+                            if (isDirToStation == true)
+                            {
+                                var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();//二楼的出库站台
+                                tostation = allOutCode.First();
+
+                                var taskout = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.StackerExecution && v.Device == obj.Entity.Code)
+                                                                                .Where(v => allOutCode.Contains(v.SrmStation))
+                                                                                .First();
+                                if (taskout != null) { isDirToStation = false; };
+
+                                if (isDirToStation == true)
+                                {
+                                    if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrTo == tostation && v.Status == TaskStatus.ConveyorExecution)) { isDirToStation = false; };
+                                }
+                                if (isDirToStation == true)
+                                {
+                                    //判断是否有小于agv小车离开取货位状态的agv任务,有的话则不允许下发
+                                    if (db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Station == tostation && v.AgvStatus < AGVTaskStatus.Complete3 && v.AgvStatus >= AGVTaskStatus.RequestOrPermission2).SplitTable(tabs => tabs.Take(2)).Any())
+                                    {
+                                        isDirToStation = false;
+                                    }
+                                }
+                            }
+
+                            //获取任务所有设备
+                            station = arrIn.First(v => v.Data.TaskNumber == task.ID);
+                            if (isDirToStation)
+                            {
+                                task.Status = TaskStatus.StackerExecution;
+                                task.AddrTo = tostation;
+                                task.LastInteractionPoint = station.Entity.Code;
+                                task.AddrNext = tostation;
+                                task.EditWho = "WCS";
+                                //task.TaskGroupKey = "1";
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行,去二楼出库点");
+                                taskInfo = task;
+                            }
+                            else//满轮入库
+                            {
+                                //station = arrIn.First(v => v.Data.TaskNumber == task.ID);
+                                //var res = WmsApi.GetLocalIn(task.ID, task.Device, station.Entity.Code);
+                                //var loc = res.ResData.CellNo.Split("-");
+                                //task.Status = TaskStatus.StackerExecution;
+                                //task.AddrTo = $"{loc[0]}-{loc[1]}-{loc[2]}";
+                                //task.LastInteractionPoint = station.Entity.Code;
+                                //task.EditWho = "WCS";
+                                //db.Default.Updateable(task).ExecuteCommand();
+                                //task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行");
+                                //taskInfo = task;
+                                throw new KnownException($"{obj.Entity.Code}不满足越库条件", LogLevelEnum.High);
+                            }
+                        }
+                        else
+                        {
+                            //获取任务所有设备
+                            station = arrIn.First(v => v.Data.TaskNumber == task.ID);
+                            //获取当前货物巷道
+                            var res = WmsApi.GetLocalIn(task.ID, task.Device, station.Entity.Code);
+                            var loc = res.ResData.CellNo.Split("-");
+                            task.Status = TaskStatus.StackerExecution;
+                            task.AddrTo = $"{loc[0]}-{loc[1]}-{loc[2]}";
+                            task.LastInteractionPoint = station.Entity.Code;
+                            task.EditWho = "WCS";
+                            db.Default.Updateable(task).ExecuteCommand();
+                            task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行");
+                            taskInfo = task;
+                        }
+                     
+                    });
+
+                    if (taskInfo == null) throw new KnownException("数据更新错误", LogLevelEnum.High);
+                    if (isDirToStation && taskInfo.BusType == "二楼湿拉空轮回立库")
+                    {
+                        World.Log($"堆垛机任务处理:开始--下发搬运二楼至一楼空轮任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                        //下发任务
+                        obj.Data.TaskNumber = taskInfo.ID;
+                        obj.Data.SLine = station.Entity.Code.ToShort(); ;
+                        obj.Data.SCol = 0;
+                        obj.Data.SLayer = 0;
+                        obj.Data.ELine = tostation.ToShort();
+                        obj.Data.ECol = 0;
+                        obj.Data.ELayer = 0;
+                        obj.Data.TaskType = SrmTaskTypeEnum.MoveGoods;
+                        obj.Data.VoucherNo++;
+                        World.Log($"堆垛机任务处理:结束---下发搬运二楼至一楼空轮任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                    }
+                    else if (isDirToStation && taskInfo.BusType == "镀铜一楼取满" && taskInfo.ProdLine == 1)
+                    {
+                        World.Log($"堆垛机任务处理:开始--下发搬运一楼至二楼满轮任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                        //下发任务
+                        obj.Data.TaskNumber = taskInfo.ID;
+                        obj.Data.SLine = station.Entity.Code.ToShort(); ;
+                        obj.Data.SCol = 0;
+                        obj.Data.SLayer = 0;
+                        obj.Data.ELine = tostation.ToShort();
+                        obj.Data.ECol = 0;
+                        obj.Data.ELayer = 0;
+                        obj.Data.TaskType = SrmTaskTypeEnum.MoveGoods;
+                        obj.Data.VoucherNo++;
+                        World.Log($"堆垛机任务处理:结束---下发搬运一楼至二楼满轮任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                    }
+                    else
+                    {
+                        var addrTo = taskInfo.AddrTo.Split("-");
+                        World.Log($"堆垛机任务处理:开始--下发入库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                        //下发任务
+                        obj.Data.TaskNumber = taskInfo.ID;
+                        obj.Data.TaskType = SrmTaskTypeEnum.Default;
+                        obj.Data.SLine = station.Entity.Code.ToShort();
+                        obj.Data.SCol = 0;
+                        obj.Data.SLayer = 0;
+                        obj.Data.ELine = addrTo[0].ToShort();
+                        obj.Data.ECol = addrTo[1].ToShort();
+                        obj.Data.ELayer = addrTo[2].ToShort();
+                        obj.Data.VoucherNo++;
+                        World.Log($"堆垛机任务处理:结束---下发入库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                    }
+                  
+                }
+                else if (enterOrOut == 3 || !lastIsOut) //出库任务
                 {
-                    //根据有货设备的任务号获取所有类型为入库状态为输送机执行中的任务
-                    var tasks = db.Default.Queryable<WCS_TaskInfo>().Where(v => (v.Type == TaskType.EnterDepot || v.Type == TaskType.EmptyInit)
-                                                                              && v.Status == TaskStatus.ConveyorExecution
-                                                                              && arrIn.Select(p => p.Data.TaskNumber).Contains(v.ID) && v.Device == obj.Entity.Code);
-                    //按条件先后排序获取一条排序后第一条结果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.Data.TaskNumber == task.ID);
-                    //获取当前货物巷道
-                    var res = WmsApi.GetLocalIn(task.ID, task.Device, station.Entity.Code);
-                    var loc = res.ResData.CellNo.Split("-");
-                    task.Status = TaskStatus.StackerExecution;
-                    task.AddrTo = $"{loc[0]}-{loc[1]}-{loc[2]}";
-                    task.LastInteractionPoint = station.Entity.Code;
-                    task.EditWho = "WCS";
-                    db.Default.Updateable(task).ExecuteCommand();
-                    task.AddWCS_TASK_DTL(db, station.Entity.Code, task.AddrTo, "任务下发堆垛机执行");
+                    //判断本次优先执行楼层,并设置下次执行时优先楼层
 
-                    taskInfo = task;
-                });
+                    var floor = obj.Entity.GetFlag<int>("FloorOut");
 
-                if (taskInfo == null) throw new KnownException("数据更新错误", LogLevelEnum.High);
-                var addrTo = taskInfo.AddrTo.Split("-");
-                World.Log($"堆垛机任务处理:开始--下发入库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
-                //下发任务
-                obj.Data.TaskNumber = taskInfo.ID;
-                obj.Data.TaskType = SrmTaskTypeEnum.Default;
-                obj.Data.SLine = station.Entity.Code.ToShort();
-                obj.Data.SCol = 0;
-                obj.Data.SLayer = 0;
-                obj.Data.ELine = addrTo[0].ToShort();
-                obj.Data.ECol = addrTo[1].ToShort();
-                obj.Data.ELayer = addrTo[2].ToShort();
-                obj.Data.VoucherNo++;
-                World.Log($"堆垛机任务处理:结束---下发入库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
-            }
-            else if (enterOrOut == 3 || !lastIsOut) //出库任务
-            {
-                //判断本次优先执行楼层,并设置下次执行时优先楼层
+                    floor = floor % 2 + 1;
+                    obj.Entity.SetFlag("FloorOut", floor);
 
-                var floor = obj.Entity.GetFlag<int>("FloorOut");
+                    //获取当前堆垛机所有的取货站台
+                    var arrOut = PutDevices.First(v => v.Key == obj.Entity.Code).Value;
 
-                floor = floor % 2 + 1;
-                obj.Entity.SetFlag("FloorOut", floor);
+                    if (!arrOut.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无放货路径点", LogLevelEnum.High);
 
-                //获取当前堆垛机所有的取货站台
-                var arrOut = PutDevices.First(v => v.Key == obj.Entity.Code).Value;
+                    //获取可以放货的设备集合
+                    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.High);
+                    //var devs = Device.All.Where(v => v.HasFlag(DeviceFlags.出库, DeviceFlags.巷道口)).Select(v => new Station(v, this.World)).ToList();
+                    //var dev = devs.Find(v => v.Entity.Code == "1026");
 
-                //获取可以放货的设备集合
-                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(); //自动
 
-                //var devs = Device.All.Where(v => v.HasFlag(DeviceFlags.出库, DeviceFlags.巷道口)).Select(v => new Station(v, this.World)).ToList();
-                //var dev = devs.Find(v => v.Entity.Code == "1026");
-                
 
 
+                    if (!arrOut.Any()) throw new KnownException($"[{obj.Entity.Code}]等待出库任务输送到位", LogLevelEnum.Low);
 
-                if (!arrOut.Any()) throw new KnownException($"[{obj.Entity.Code}]等待出库任务输送到位", LogLevelEnum.Mid);
+                    WCS_TaskInfo taskInfo = null;
 
-                WCS_TaskInfo taskInfo = null;
+                    SqlSugarHelper.Do(db =>
+                    {
+                        var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();
+
+                        //按条件先后排序获取一条排序后第一条结果1.优先级2.所在楼层与本次优先执行楼层
+                        var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.WaitingToExecute && v.Device == obj.Entity.Code)
+                                                                       .Where(v => allOutCode.Contains(v.SrmStation))
+                                                                       .OrderByDescending(v => v.Priority)
+                                                                       .OrderByDescending(v => v.Floor == floor ? 1 : 0)
+                                                                       .OrderBy(v => v.AddTime)
+                                                                       .First();
+                        if (task == null) return;//throw new KnownException($"{obj.Entity.Code}未找到出库任务", LogLevelEnum.High);
+
+                        string addrTo = task.SrmStation;
+                        if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrTo == task.AddrTo && v.Status == TaskStatus.ConveyorExecution)) return;
+                        //判断agv任务存在没有离开取货位的,则卡控
+                        if (db.Default.Queryable<WCS_AgvTaskInfo>().Where(v =>  v.Station == task.AddrTo && v.AgvStatus < AGVTaskStatus.Complete3 && v.AgvStatus>= AGVTaskStatus.RequestOrPermission2 ).SplitTable(tabs => tabs.Take(2)).Any())
+                        {
+                            return;
+                        }
+                        var taskId = task.ID;
+
+                        //判断是否是二深位任务
+                        var addrFrom = task.AddrFrom.Split("-");
+                        if (addrFrom[4] == "02")
+                        {
+                            var res = WmsApi.AddWcsMoveTask(task.ID);
+                            switch (res.ResData.ResType)
+                            {
+                                case WmsApiMoveTask.允许2升位执行:
+                                    break;
 
-                SqlSugarHelper.Do(db =>
-               {
-                   var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();
-
-                   //按条件先后排序获取一条排序后第一条结果1.优先级2.所在楼层与本次优先执行楼层
-                   var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.WaitingToExecute && v.Device == obj.Entity.Code)
-                                                                  .Where(v => allOutCode.Contains(v.SrmStation))
-                                                                  .OrderByDescending(v => v.Priority)
-                                                                  .OrderByDescending(v => v.Floor == floor ? 1 : 0)
-                                                                  .OrderBy(v => v.AddTime)
-                                                                  .First();
-                   if (task == null) throw new KnownException($"{obj.Entity.Code}未找到出库任务", LogLevelEnum.High);
-                   var taskId = task.ID;
-
-                   //判断是否是二深位任务
-                   var addrFrom = task.AddrFrom.Split("-");
-                   if (addrFrom[4] == "02")
-                   {
-                       var res = WmsApi.AddWcsMoveTask(task.ID);
-                       switch (res.ResData.ResType)
-                       {
-                           case WmsApiMoveTask.允许2升位执行:
-                               break;
-
-                           case WmsApiMoveTask.执行移库任务:
-                               throw new KnownException($"堆垛机{obj.Entity.Code}需要先执行移库任务", LogLevelEnum.Mid);
-
-                           case WmsApiMoveTask.一深位有出库任务:
-                               task = db.Default.Queryable<WCS_TaskInfo>()
-                                                .Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.WaitingToExecute)
-                                                .Where(v => allOutCode.Contains(v.SrmStation) && v.AddrFrom == res.ResData.CellNo)
-                                                .First() ?? throw new KnownException($"请尽快搬离{obj.Entity.Code}二楼出库口满轮,当前堆垛机出库任务呗阻塞", LogLevelEnum.Mid);
-                               break;
-                       };
-                       if (res.ResData.ResType == WmsApiMoveTask.执行移库任务) return;
-                       if (res.ResData.ResType == WmsApiMoveTask.一深位有出库任务 && res.ResData.CellNo != task.AddrFrom) return;
-                   }
-
-                   task.Status = TaskStatus.StackerExecution;
-                   task.LastInteractionPoint = task.Device;
-                   task.EditWho = "WCS";
-                   db.Default.Updateable(task).ExecuteCommand();
-                   task.AddWCS_TASK_DTL(db, task.Device, task.SrmStation, "任务下发堆垛机执行");
-                   taskInfo = task;
-               });
-
-                if (taskInfo == null) throw new KnownException("数据更新错误", LogLevelEnum.High);
-
-                var addrFrom = taskInfo.AddrFrom.Split("-");
-                World.Log($"堆垛机任务处理:开始--下发出库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
-                obj.Data.TaskNumber = taskInfo.ID;
-                obj.Data.SLine = addrFrom[0].ToShort();
-                obj.Data.SCol = addrFrom[1].ToShort();
-                obj.Data.SLayer = addrFrom[2].ToShort();
-                obj.Data.ELine = taskInfo.SrmStation.ToShort();
-                obj.Data.ECol = 0;
-                obj.Data.ELayer = 0;
-                obj.Data.TaskType = SrmTaskTypeEnum.Default;
-                obj.Data.VoucherNo++;
-                World.Log($"堆垛机任务处理:结束---下发出库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
-            }
+                                case WmsApiMoveTask.执行移库任务:
+                                    throw new KnownException($"堆垛机{obj.Entity.Code}需要先执行移库任务", LogLevelEnum.Mid);
+
+                                case WmsApiMoveTask.一深位有出库任务:
+                                    task = db.Default.Queryable<WCS_TaskInfo>()
+                                                     .Where(v => v.Type == TaskType.OutDepot && v.Status == TaskStatus.WaitingToExecute)
+                                                     .Where(v => allOutCode.Contains(v.SrmStation) && v.AddrFrom == res.ResData.CellNo)
+                                                     .First() ?? throw new KnownException($"请尽快搬离{obj.Entity.Code}二楼出库口满轮,当前堆垛机出库任务呗阻塞", LogLevelEnum.Mid);
+                                    break;
+                            };
+                            if (res.ResData.ResType == WmsApiMoveTask.执行移库任务) return;
+                            if (res.ResData.ResType == WmsApiMoveTask.一深位有出库任务 && res.ResData.CellNo != task.AddrFrom) return;
+                        }
+
+                        task.Status = TaskStatus.StackerExecution;
+                        task.LastInteractionPoint = task.Device;
+                        task.EditWho = "WCS";
+                        db.Default.Updateable(task).ExecuteCommand();
+                        task.AddWCS_TASK_DTL(db, task.Device, task.SrmStation, "任务下发堆垛机执行");
+                        taskInfo = task;
+                    });
+
+                    if (taskInfo == null) return;//throw new KnownException("数据更新错误", LogLevelEnum.High);
+
+                    var addrFrom = taskInfo.AddrFrom.Split("-");
+                    World.Log($"堆垛机任务处理:开始--下发出库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                    obj.Data.TaskNumber = taskInfo.ID;
+                    obj.Data.SLine = addrFrom[0].ToShort();
+                    obj.Data.SCol = addrFrom[1].ToShort();
+                    obj.Data.SLayer = addrFrom[2].ToShort();
+                    obj.Data.ELine = taskInfo.SrmStation.ToShort();
+                    obj.Data.ECol = 0;
+                    obj.Data.ELayer = 0;
+                    obj.Data.TaskType = SrmTaskTypeEnum.Default;
+                    obj.Data.VoucherNo++;
+                    World.Log($"堆垛机任务处理:结束---下发出库任务[{obj.Data.TaskNumber}][{obj.Data.SLine}][{obj.Data.SCol}][{obj.Data.SLayer}][{obj.Data.ELine}][{obj.Data.ECol}][{obj.Data.ELayer}][{obj.Data.TaskType}][{obj.Data.VoucherNo}]", LogLevelEnum.Mid);
+                }
+
+                #endregion 出入库
+
+            });
 
-            #endregion 出入库
+            
         }
 
         public override bool Select(Device dev)
         {
             //return dev.Code == "SRM2";
-            return dev.HasFlag(DeviceFlags.堆垛机);
+            return dev.Code is "SRM1" or "SRM2" or "SRM3" or "SRM4";
+           
         }
     }
 }

+ 25 - 4
WCS.WorkEngineering/Systems/一楼入库工位处理系统.cs

@@ -43,6 +43,7 @@ namespace WCS.WorkEngineering.Systems
                 {
                     var db = _db.Default;
                     WCS_TaskInfo taskInfo = null;
+                    if (!obj.Data3.Status.HasFlag(StatusEunm.PH_Status) && obj.Data2.Request == 0) return;
                     //判断是否有空轮初始化任务
                     if (db.Queryable<WCS_TaskInfo>().Count(v => v.Type == TaskType.EmptyInit && v.Status == TaskStatus.WaitingToExecute && v.SrmStation == obj.Entity.Code) > 1)
                     {
@@ -57,7 +58,7 @@ namespace WCS.WorkEngineering.Systems
                         //获取RFID
                         barcode = BCRS.GetBCRCode(obj.Entity.Code);
                         //跟据RFID获取对应的任务
-                        taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.BarCode == barcode) ?? throw new KnownException($"未找到RFID:{barcode}对应WCS任务", LogLevelEnum.Mid);
+                        taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.BarCode == barcode) ?? throw new KnownException($"未找到RFID:{barcode}对应WCS任务,请检查扫码是否异常", LogLevelEnum.Mid);
                         if (taskInfo.Status != Entity.TaskStatus.AGVExecution)
                         {
                             if (db.Queryable<WCS_TaskDtl>().SplitTable(v => v.Take(2)).Any(v => v.ParentTaskCode == taskInfo.ID && v.Desc.Contains("等待分配货位后堆垛机进行取货"))) return;
@@ -73,8 +74,18 @@ namespace WCS.WorkEngineering.Systems
                         }
                         //获取称重
                         var dev91 = Device.All.Where(v => v.Code == obj.Entity.Code).Select(v => new Device<IStation91>(v, this.World)).FirstOrDefault();
-                        taskInfo.Weight = dev91.Data.Weight;
-                        if (taskInfo.Weight < 200) throw new KnownException($"称重结果错误:{taskInfo.Weight}", LogLevelEnum.Mid);
+
+                        //if (obj.Entity.Code != "1117")
+                        //{
+                            taskInfo.Weight = dev91.Data.Weight;
+                        //}
+                        //else
+                        //{
+                        //    taskInfo.Weight = 800;
+                        //}
+
+                        
+                        if (taskInfo.Weight < 130) throw new KnownException($"称重结果错误:{taskInfo.Weight}", LogLevelEnum.Mid);
                         //上抛重量
                         try { WmsApi.WcsUploadInfo(taskInfo.ID, (decimal)taskInfo.Weight, taskInfo.BarCode); } catch (Exception ex) { World.Log(ex.Message, LogLevelEnum.Mid); }
                     }
@@ -82,7 +93,16 @@ namespace WCS.WorkEngineering.Systems
                     {
                         //获取称重
                         var dev91 = Device.All.Where(v => v.Code == obj.Entity.Code).Select(v => new Device<IStation91>(v, this.World)).FirstOrDefault();
-                        taskInfo.Weight = dev91.Data.Weight;
+
+                        //if (obj.Entity.Code != "1117")
+                        //{
+                            taskInfo.Weight = dev91.Data.Weight;
+                        //}
+                        //else
+                        //{
+                        //    taskInfo.Weight = 200;
+                        //}
+                        //taskInfo.Weight = dev91.Data.Weight;
                         if (taskInfo.Weight < 140) throw new KnownException($"称重结果错误:{taskInfo.Weight}", LogLevelEnum.Mid);
                         //上抛重量
                         try { WmsApi.WcsUploadInfo(taskInfo.ID, (decimal)taskInfo.Weight, taskInfo.BarCode); } catch (Exception ex) { World.Log(ex.Message, LogLevelEnum.Mid); }
@@ -99,6 +119,7 @@ namespace WCS.WorkEngineering.Systems
             {
                 throw new KnownException(ex.Message, LogLevelEnum.High);
             }
+            if (task == null) return;
             obj.Data.TaskNumber = task.ID;
             obj.Data.VoucherNo++;
         }

+ 132 - 3
WCS.WorkEngineering/Systems/一楼出库工位处理系统.cs

@@ -1,6 +1,7 @@
 using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using ServiceCenter.SqlSugars;
+using System;
 using System.ComponentModel;
 using WCS.Core;
 using WCS.Entity;
@@ -39,9 +40,10 @@ namespace WCS.WorkEngineering.Systems
                     {
                         //当前站台是否有任务在执行
                         var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.AddrTo == obj.Entity.Code && v.Status < Entity.TaskStatus.AGVExecution).OrderByDescending(v => v.AddTime).First();
-                        if (task != null) //有任务
+                        if (db.Default.Queryable<WCS_TaskInfo>().Where(v => v.AddrTo == obj.Entity.Code && v.Status == Entity.TaskStatus.WaitingToExecute).Count() > 1) return;
+                        if (task != null && (task.BusType == "一楼立库出空轮" || task.TaskGroupKey == "1")) //有任务
                         {
-                            if (task.AgvTaskID == 0) throw new KnownException($"WCS任务[{task.ID}],等待AGV申请任务", LogLevelEnum.Mid);
+                            if (task.AgvTaskID == 0) throw new KnownException($"WCS任务[{task.ID}],还没有下发给AGV", LogLevelEnum.Mid);
                             else
                             {
                                 //检查对应的AGV任务状态是否大于退出储位状态
@@ -61,11 +63,138 @@ namespace WCS.WorkEngineering.Systems
                         }
                         else //无任务
                         {
-                            result = true;
+                            //判断有没有二楼分配过巷道的空轮任务
+                            string tunnel = "";
+                            switch (obj.Entity.Code)
+                            {
+                                case "1012":
+                                    tunnel = "1";
+                                    break;
+                                case "1014":
+                                    tunnel = "2";
+                                    break;
+                                case "1016":
+                                    tunnel = "3";
+                                    break;
+                                case "1118" or "1131" or "1132" or "1133" or "1134" or "1135" or "1136" or "1137" or "1139":
+                                    tunnel = "4";
+                                    break;
+                            }
+                            if (db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Tunnel == tunnel && v.Type == TaskType.EnterDepot && v.BusType == "二楼湿拉空轮回立库").Any())
+                            {
+                                result = false;
+                            }
+                            else
+                            {
+                                result = true;
+                            }
                         }
                     });
                     if (result) WmsApi.ApplyStockOutTask(obj.Entity.Code);
                 }
+                //下发满轮任务到agv
+                else
+                {
+
+                    SqlSugarHelper.Do(db =>
+                    {
+
+                        var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First();
+
+                        if (task != null && (task.BusType == "一楼立库出空轮" || task.TaskGroupKey == "1")) //有任务
+                        {
+                            if (task.AgvTaskID > 0 && task.BusType == "一楼立库出空轮")
+                            {
+                                //直接下发给agv
+                                SqlSugarHelper.Do(db =>
+                                {
+                                    //当前站台是否有任务在执行
+                                    var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First();
+                                    if (task == null) throw new KnownException($"未找到空轮wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low);
+
+                                    var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID).First();
+                                    if (agvTask == null)
+                                    {
+                                        throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid);
+                                    }
+                                    if (string.IsNullOrEmpty(agvTask.AgvID))
+                                    {
+                                        var res = AgvApi.一楼空轮出库下发AGV(task.BarCode + "@", task.AddrTo, task.AddrTo, Guid.NewGuid().ToString().Replace("-", ""), "1");
+                                        agvTask.Status = AGVTaskStatus.Confirm;
+                                        agvTask.AgvID = res.data;
+                                        db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand();
+                                        //更新WCS数据
+                                        task.Status = Entity.TaskStatus.AGVExecution;
+                                        db.Default.Updateable(task).ExecuteCommand();
+                                        task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}");
+                                    }
+                                });
+                                //throw new KnownException($"WCS任务[{task.ID}],等待AGV申请任务", LogLevelEnum.Mid);
+                            }
+                            else if (task.TaskGroupKey == "1" && !db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID && v.TaskType == AGVTaskType.CallForMaterial).Any())
+                            {
+                                //直接下发给agv
+                                SqlSugarHelper.Do(db =>
+                                {
+                                    //当前站台是否有任务在执行
+                                    var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First();
+                                    if (task == null) throw new KnownException($"未找到空轮wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low);
+
+                                    var agvTask1 = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID && v.Status < AGVTaskStatus.MissionCompleted).First();
+                                    if (agvTask1 != null)
+                                    {
+                                        throw new KnownException($"[{task.AgvTaskID}]已经存在AGV任务,不需要重复下发", LogLevelEnum.Mid);
+                                    }
+
+                                    var res = AgvApi.一楼空轮出库下发AGV(task.BarCode+"@", task.AddrTo, task.AddrTo, Guid.NewGuid().ToString().Replace("-", ""), "1");
+
+                                    //创建AGV任务
+                                    var agvTask = new WCS_AgvTaskInfo()
+                                    {
+                                        ID = db.GetAGVTaskId(),
+                                        TaskType = AGVTaskType.CallForMaterial,
+                                        Status = AGVTaskStatus.Confirm,
+                                        Station = task.SrmStation,
+                                        Position = task.AddrTo,
+                                        AgvID = res.data,
+                                        AddWho = "WCS"
+                                    };
+                                    db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                                    task.AgvTaskID = agvTask.ID;
+
+                                    //更新WCS数据
+                                    task.Status = Entity.TaskStatus.AGVExecution;
+                                    db.Default.Updateable(task).ExecuteCommand();
+                                    task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}");
+
+                                });
+                            }
+
+                        }
+                        else
+                        {
+                            //当前站台是否有任务在执行
+                            if (task == null) throw new KnownException($"未找到wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low);
+                            if (task.BusType == "一楼出满轮" && task.AgvTaskID > 0)
+                            {
+                                var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID).First();
+                                if (agvTask == null)
+                                {
+                                    throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid);
+                                }
+                                var res = AgvApi.一楼满轮出库(task.BarCode, agvTask.Station, agvTask.Position, Guid.NewGuid().ToString().Replace("-", ""), "1");
+                                agvTask.Status = AGVTaskStatus.Confirm;
+                                agvTask.AgvID = res.data;
+                                db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand();
+                                //更新WCS数据
+                                task.Status = Entity.TaskStatus.AGVExecution;
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}");
+                            }
+                        }
+                       
+                    });
+                }
             }
             finally
             {

+ 3 - 3
WCS.WorkEngineering/Systems/二楼入库工位处理系统.cs

@@ -58,7 +58,7 @@ namespace WCS.WorkEngineering.Systems
 
                  if (taskInfo == null)
                  {
-                     taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data.TaskNumber && v.Type == TaskType.EnterDepot);
+                     taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data.TaskNumber && v.Type == TaskType.EnterDepot && v.SrmStation == obj.Entity.Code);
                      if (taskInfo == null) throw new KnownException($"未找到任务[{obj.Data.TaskNumber}],或该任务不是入库任务", LogLevelEnum.Mid);
                      if (taskInfo.Status != Entity.TaskStatus.AGVExecution)
                      {
@@ -70,7 +70,7 @@ namespace WCS.WorkEngineering.Systems
 
                  #endregion 非空轮初始化入库任务
 
-                 if (obj.Entity.Code == "1025")//获取称重
+                 if (obj.Entity.Code == "1025" || obj.Entity.Code == "1127")//获取称重
                  {
                      var dev91 = Device.All.Where(v => v.Code == obj.Entity.Code).Select(v => new Device<IStation91>(v, this.World)).FirstOrDefault();
                      taskInfo.Weight = dev91.Data.Weight;
@@ -91,7 +91,7 @@ namespace WCS.WorkEngineering.Systems
 
         public override bool Select(Device dev)
         {
-            return dev.HasFlag(DeviceFlags.二楼入库口);
+            return dev.Code is "1025" or "1023" or "1021" or "1127";
         }
     }
 }

+ 43 - 11
WCS.WorkEngineering/Systems/二楼出库工位处理系统.cs

@@ -26,17 +26,49 @@ namespace WCS.WorkEngineering.Systems
             if (!obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.PH_Status)) throw new KnownException("无光电", LogLevelEnum.Low);
             SqlSugarHelper.Do(db =>
             {
-                var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution) ?? throw new KnownException("无可执行任务", LogLevelEnum.Mid);               
-                var agv = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).First(v => v.ID == task.AgvTaskID && v.Status == AGVTaskStatus.NewBuild) ?? throw new KnownException("未找到对应的AGV任务", LogLevelEnum.Mid);
-                var res = IwmsApi.满轮出库(task.MatCode, task.AddrTo, task.ID.ToString(), task.BarCode, task.InvBarCode, task.IsSurplus, task.IsRework, task.IsFast, task.Grade, task.WorkBench);
-                agv.Status = AGVTaskStatus.Confirm;
-                agv.AgvID = res.data;
-                agv.Station = obj.Entity.Code;
-                agv.Position = obj.Entity.Code;
-                db.Default.Updateable(agv).SplitTable().ExecuteCommand();
-                task.Status = Entity.TaskStatus.AGVExecution;
-                db.Default.Updateable(task).ExecuteCommand();
-                task.AddWCS_TASK_DTL(db, obj.Entity.Code, "AGV", $"任务已下发AGV,AGVID:{agv.AgvID}");
+                var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution) ?? throw new KnownException("无可执行任务", LogLevelEnum.Mid);
+                if (task.ProdLine == 1)
+                {
+                    //var agv = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).First(v => v.ID == task.AgvTaskID && v.Status == AGVTaskStatus.NewBuild) ?? throw new KnownException("未找到对应的AGV任务", LogLevelEnum.Mid);
+                    var res = IwmsApi.满轮出库(task.MatCode, task.AddrTo, task.ID.ToString(), task.BarCode, task.InvBarCode, task.IsSurplus, task.IsRework, task.IsFast, task.Grade, task.WorkBench, task.AddWho, true);
+
+                    var agv = new WCS_AgvTaskInfo()
+                    {
+                        ID = db.GetAGVTaskId(),
+                        TaskType = AGVTaskType.CallMaterial,
+                        Status = AGVTaskStatus.Confirm,
+                        Station = obj.Entity.Code,
+                        Position = obj.Entity.Code,
+                        AddWho = "WCS",
+                        AgvID = res.data,
+                    };
+                    db.Default.Insertable(agv).SplitTable().ExecuteCommand();
+
+
+                    //agv.Status = AGVTaskStatus.Confirm;
+                    //agv.AgvID = res.data;
+                    //agv.Station = obj.Entity.Code;
+                    //agv.Position = obj.Entity.Code;
+                    //db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
+                    task.AgvTaskID = agv.ID;
+                    task.Status = Entity.TaskStatus.AGVExecution;
+                    db.Default.Updateable(task).ExecuteCommand();
+                    task.AddWCS_TASK_DTL(db, obj.Entity.Code, "AGV", $"任务已下发AGV,AGVID:{agv.AgvID}");
+                }
+                else
+                {
+                    var agv = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).First(v => v.ID == task.AgvTaskID && v.Status == AGVTaskStatus.NewBuild) ?? throw new KnownException("未找到对应的AGV任务", LogLevelEnum.Mid);
+                    var res = IwmsApi.满轮出库(task.MatCode, task.AddrTo, task.ID.ToString(), task.BarCode, task.InvBarCode, task.IsSurplus, task.IsRework, task.IsFast, task.Grade, task.WorkBench, task.AddWho);
+                    agv.Status = AGVTaskStatus.Confirm;
+                    agv.AgvID = res.data;
+                    agv.Station = obj.Entity.Code;
+                    agv.Position = obj.Entity.Code;
+                    db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
+                    task.Status = Entity.TaskStatus.AGVExecution;
+                    db.Default.Updateable(task).ExecuteCommand();
+                    task.AddWCS_TASK_DTL(db, obj.Entity.Code, "AGV", $"任务已下发AGV,AGVID:{agv.AgvID}");
+                }
+               
             });
         }
 

二進制
WCS.WorkEngineering/WCS.WorkEngineering.7z


+ 120 - 2
WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs

@@ -1,12 +1,14 @@
 using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using ServiceCenter.WebApi;
+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.WebApi.Models.WMS.Request;
 using WCS.WorkEngineering.WebApi.Models.WMS.Response;
 
+
 namespace WCS.WorkEngineering.WebApi.Controllers
 {
     /// <summary>
@@ -44,6 +46,10 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <returns></returns>
         public static GenAgvSchedulingTaskResponse 满轮入库(string ctnrCode, string position, string taskCode, string priority)
         {
+            if (position == "1017")
+            {
+                position = "40";
+            }
             return GenAgvSchedulingTask("iwms_third", ctnrCode, "4", new List<positionCodeClass>()
             {
                 new positionCodeClass(){ //取货机台
@@ -61,6 +67,33 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             }, priority, taskCode, "ZTGT03", "1");
         }
 
+        ///// <summary>
+        /////  一楼满轮出库
+        ///// </summary>
+        ///// <param name="ctnrCode">RFID</param>
+        ///// <param name="position">取货机台</param>
+        ///// <param name="taskCode">WMS任务号</param>
+        ///// <param name="priority">优先级</param>
+        ///// <returns></returns>
+        //public static GenAgvSchedulingTaskResponse 一楼满轮入库(string ctnrCode, string position, string taskCode, string priority)
+        //{
+        //    return GenAgvSchedulingTask("iwms_third", ctnrCode, "4", new List<positionCodeClass>()
+        //    {
+        //        new positionCodeClass(){ //取货机台
+        //            positionCode=position,
+        //            type="00"
+        //        },
+        //        new positionCodeClass(){ //巷道分配点
+        //            positionCode="HJLK",
+        //            type="00"
+        //        },
+        //        new positionCodeClass(){ //预分配放货点
+        //            positionCode="1015",
+        //            type="00"
+        //        }
+        //    }, priority, taskCode, "ZTGT03", "1");
+        //}
+
         /// <summary>
         ///  机台补空
         /// </summary>
@@ -95,7 +128,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         }
 
         /// <summary>
-        ///  机台补满
+        ///  一楼满轮出库
         /// </summary>
         /// <param name="ctnrCode">RFID</param>
         /// <param name="position1">取货站台</param>
@@ -103,8 +136,12 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="taskCode">WMS任务号</param>
         /// <param name="priority">优先级</param>
         /// <returns></returns>
-        public static GenAgvSchedulingTaskResponse 机台补满(string ctnrCode, string position1, string position2, string taskCode, string priority)
+        public static GenAgvSchedulingTaskResponse 一楼满轮出库(string ctnrCode, string position1, string position2, string taskCode, string priority)
         {
+            if (position1 == "1018")
+            {
+                position1 = "41";
+            }
             return GenAgvSchedulingTask("iWMS", ctnrCode, "1", new List<positionCodeClass>()
             {
                 new positionCodeClass(){ //取货站台
@@ -118,6 +155,35 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             }, priority, taskCode, "ZTGT21", "-1");
         }
 
+        /// <summary>
+        ///  一楼空轮出库下发AGV
+        /// </summary>
+        /// <param name="ctnrCode">RFID</param>
+        /// <param name="position1">取货站台</param>
+        /// <param name="position2">放货机台</param>
+        /// <param name="taskCode">WMS任务号</param>
+        /// <param name="priority">优先级</param>
+        /// <returns></returns>
+        public static GenAgvSchedulingTaskResponse 一楼空轮出库下发AGV(string ctnrCode, string position1, string position2, string taskCode, string priority)
+        {
+            if (position1 == "1018")
+            {
+                position1 = "41";
+            }
+            return GenAgvSchedulingTask2("iwms", ctnrCode, "4", new List<positionCodeClass>()
+            {
+                new positionCodeClass(){ //取货站台
+                    positionCode=position1,
+                    type="00"
+                },
+                new positionCodeClass(){ //放货机台
+                    positionCode="500",
+                    type="04"
+                }
+            }, priority, taskCode, "ZTGT22", "-1");
+        }
+
+
         /// <summary>
         ///  Agv任务单生成接口
         /// </summary>
@@ -154,6 +220,29 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             return res;
         }
 
+        public static GenAgvSchedulingTaskResponse GenAgvSchedulingTask2(string clienCode, string ctnrCode, string ctnrTyp, List<positionCodeClass> positionCodePath, string priority, string taskCode, string taskType, string hjTaskTy)
+        {
+            var res = APICaller.CallApi2<GenAgvSchedulingTaskResponse>(AgvUrl + "/rcms/services/rest/hikRpcService/genAgvSchedulingTask", new GenAgvSchedulingTaskRequest
+            {
+                clientCode = clienCode,
+                ctnrCode = ctnrCode,
+                ctnrTyp = ctnrTyp,
+                interfaceName = "genAgvSchedulingTask",
+                positionCodePath = positionCodePath,
+                reqCode = Guid.NewGuid().ToString().Replace("-", ""),
+                taskCode = taskCode,
+                taskTyp = taskType,
+                reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+                tokenCode = "56898661ea976b748f328cefa6960434",
+            });
+            if (res.code != AgvResponseCode.Success)
+            {
+                throw new KnownException("一楼空轮下任务,海康接口报错:"+res.message, LogLevelEnum.High);
+            }
+            return res;
+        }
+
+
         #endregion 任务单生成
 
         #region 继续执行任务
@@ -167,6 +256,14 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <exception cref="KnownException"></exception>
         public static ContinueTaskResponse ContinueTask(string taskCode, string nextPositionCode)
         {
+            if (nextPositionCode == "1017")
+            {
+                nextPositionCode = "40";
+            }
+            else if (nextPositionCode == "1018")
+            {
+                nextPositionCode = "41";
+            }
             var res = APICaller.CallApi2<ContinueTaskResponse>(AgvUrl + "/rcms/services/rest/hikRpcService/continueTask", new ContinueTaskRequest
             {
                 reqCode = Guid.NewGuid().ToString().Replace("-", ""),
@@ -205,5 +302,26 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             }
             return res;
         }
+        /// <summary>
+        /// 一键抹除
+        /// </summary>
+        /// <param name="AGVtaskCode">AGV任务号</param>
+        /// <returns></returns>
+        /// <exception cref="KnownException"></exception>
+        public static CancelTaskResponse DelAgvTask(string AGVtaskCode, string reqCode)
+        {
+            var res = APICaller.CallApi2<CancelTaskResponse>(AgvUrl + "/rcms/services/rest/hikRpcService/oneKeyCleanTaskCode", new DelTaskRequest
+            {
+                reqCode = Guid.NewGuid().ToString().Replace("-", ""),
+                cleanTaskCode = AGVtaskCode,
+                cancelReqCode = reqCode,
+            });
+
+            if (res.code != AgvResponseCode.Success)
+            {
+                throw new KnownException(res.message, LogLevelEnum.High);
+            }
+            return res;
+        }
     }
 }

+ 96 - 40
WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -24,6 +24,8 @@ namespace WCS.WorkEngineering.WebApi.Controllers
     [Route("api/[controller]/[action]")]
     public class AgvController : ControllerBase
     {
+        static object lockerApplyEmptySpool = new object();
+        static object lockerAgvCallback = new object();
         /// <summary>
         ///  AGV任务下发测试
         /// </summary>
@@ -71,45 +73,65 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         [HttpPost]
         public ApplyEmptySpoolResponse ApplyEmptySpool([FromBody] AgvFillEmptySpaceRequest reqDto)
         {
+            return new ApplyEmptySpoolResponse()
+            {
+                ResCode = Models.WMS.Response.ResponseStatusCodeEnum.AccountError,
+                ResMsg = "接口已禁用,已经改为主动下发方式"
+            };
             var key = $"WCS:Lock:AGV:{nameof(ApplyEmptySpool)}";
             ApplyEmptySpoolResponse agvFill = new ApplyEmptySpoolResponse();
-            try
+            lock (lockerApplyEmptySpool)
             {
+                LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"传入参数--{JsonConvert.SerializeObject(reqDto)}");
                 if (RedisHub.Default.Get(key) != null)
                 {
                     agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                     agvFill.ResMsg = $"[{nameof(ApplyEmptySpool)}]--触发并发管控";
+                    return agvFill;
                 }
-                else
-                {
-                    RedisHub.Default.Set(key, nameof(ApplyEmptySpool));
-                    LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"传入参数--{JsonConvert.SerializeObject(reqDto)}");
+                RedisHub.Default.Set(key, nameof(ApplyEmptySpool), 60);
+            }
+            try
+            {
 
-                    try
+                try
+                {
+                    agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
+                    if (!World.IsStart)
                     {
                         agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
-                        if (!World.IsStart)
-                        {
-                            agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
-                            agvFill.ResMsg = "WCS初始化中";
-                            return agvFill;
-                        }
-                        var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke("输送机") as List<Station>;
+                        agvFill.ResMsg = "WCS初始化中";
+                        return agvFill;
+                    }
+                    var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke("输送机") as List<Station>;
 
-                        // 检测三个站台是否有货
-                        obj = obj.Where(v => v.Entity.Code is "1012" or "1014" or "1016").Where(v => v.Data3.Status.HasFlag(StatusEunm.PH_Status)).ToList();
-                        if (!obj.Any())
+                    // 检测三个站台是否有货
+                    obj = obj.Where(v => v.Entity.Code is "1012" or "1014" or "1016").Where(v => v.Data3.Status.HasFlag(StatusEunm.PH_Status)).ToList();
+                    if (!obj.Any())
+                    {
+                        agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
+                        agvFill.ResMsg = "无空轮";
+                        return agvFill;
+                    }
+                    SqlSugarHelper.Do(db =>
+                    {
+                        //查询此请求是否已经有过任务
+                        var existtask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2)).Where(v =>  v.EditWho == reqDto.Reqid ).Select(v => v).ToList();
+                        if (existtask != null && existtask.Any())
                         {
-                            agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
-                            agvFill.ResMsg = "无空轮";
-                            return agvFill;
+                            var temp = existtask.ToList().First();
+                            agvFill.LocCode = temp.Station;
+                            agvFill.SpoolType = "4";
+                            agvFill.ResMsg = "";
+                            agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.Sucess;
+                            agvFill.TaskCode = temp.AgvID;
                         }
-                        SqlSugarHelper.Do(db =>
+                        else
                         {
                             var res = WmsApi.GetTunnelEmptyConCount();
 
                             var agvStations = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2))
-                                              .Where(v => v.Status < AGVTaskStatus.Complete3 && v.TaskType == AGVTaskType.CallForMaterial).Select(v => v.Station).ToList();
+                                                .Where(v => v.Status < AGVTaskStatus.Complete3 && (v.TaskType == AGVTaskType.CallForMaterial || (v.TaskType == AGVTaskType.CallMaterial && v.WorkShop == 111 && v.Status >= AGVTaskStatus.Confirm))).Select(v => v.Station).ToList();
                             obj = obj.Where(v => !agvStations.Contains(v.Entity.Code)).ToList();
                             if (!obj.Any())
                             {
@@ -130,6 +152,13 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                             var stationNo = res.ResDataList.OrderBy(v => v.Count).Select(v => v.Tunnel.ToString()).ToList();
                             var dev = obj.MinBy(v => stationNo.IndexOf(v.Entity.Code));
                             var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == dev.Data.TaskNumber) ?? throw new Exception("无有效任务");
+
+                            if (task.BusType != "一楼立库出空轮" && task.TaskGroupKey != "1")
+                            {
+                                agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
+                                agvFill.ResMsg = $"{dev.Entity.Code}不可用";
+                                return;
+                            }
                             var id = db.GetAGVTaskId();
                             var agv = new WCS_AgvTaskInfo()
                             {
@@ -138,7 +167,8 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                 TaskType = AGVTaskType.CallForMaterial,
                                 Status = AGVTaskStatus.NewBuild,
                                 Station = dev.Entity.Code,
-                                AddWho = "WCS"
+                                AddWho = "WCS",
+                                EditWho = reqDto.Reqid//请求id暂存
                             };
                             //创建对应的AGV任务
                             db.Default.Insertable(agv).SplitTable().ExecuteCommand();
@@ -153,15 +183,17 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                             agvFill.ResMsg = "";
                             agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.Sucess;
                             agvFill.TaskCode = agv.AgvID;
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
-                        agvFill.ResMsg = ex.Message;
-                    }
-                    LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"返回参数{JsonConvert.SerializeObject(agvFill)}");
+                        }
+
+                    });
+                }
+                catch (Exception ex)
+                {
+                    agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
+                    agvFill.ResMsg = ex.Message;
                 }
+                LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"返回参数{JsonConvert.SerializeObject(agvFill)}");
+
             }
             finally
             {
@@ -178,25 +210,41 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         [HttpPost]
         public AgvCallbackResponse AgvCallback([FromBody] AgvCallbackRequest reqDto)
         {
-            var key = $"WCS:Lock:AGV:{nameof(AgvCallback)}";
+            return new AgvCallbackResponse()
+            {
+                code = AgvResponseCode.Error,
+                message = "接口已禁用"
+            };
+
+            var key = $"WCS:Lock:AGV:{nameof(AgvCallback)+ reqDto.taskCode}";
             var res = new AgvCallbackResponse() { code = AgvResponseCode.Fail, message = "失败" };
-            try
+            lock (lockerAgvCallback)
             {
                 if (RedisHub.Default.Get(key) != null)
                 {
                     res.code = AgvResponseCode.Error;
-                    res.message = $"[{nameof(AgvCallback)}]--触发并发管控";
+                    res.message = $"[{nameof(AgvCallback) + reqDto.taskCode}]--触发并发管控";
+                    return res;
                 }
-                else
-                {
-                    RedisHub.Default.Set(key, nameof(AgvCallback));
+                RedisHub.Default.Set(key, nameof(AgvCallback), 60);
+            }
+            try
+            {
+                //if (RedisHub.Default.Get(key) != null)
+                //{
+                //    res.code = AgvResponseCode.Error;
+                //    res.message = $"[{nameof(AgvCallback)}]--触发并发管控";
+                //}
+                //else
+                //{
+                    //RedisHub.Default.Set(key, nameof(AgvCallback));
                     WCS_TaskInfo taskInfo = null;
                     try
                     {
                         SqlSugarHelper.Do(db =>
                         {
                             //跟据AGVid找到对应的AGV任务
-                            var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2)).First(v => v.AgvID == reqDto.taskCode && v.Status < AGVTaskStatus.MissionCompleted);
+                            var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.AgvID == reqDto.taskCode && v.Status < AGVTaskStatus.MissionCompleted).SplitTable(tabs => tabs.Take(2)).First();
                             if (agvTask == null)
                             {
                                 res.code = AgvResponseCode.Fail;
@@ -215,14 +263,22 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                     //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
                                     //    break;
 
-                                    case "applyContinue": //表示请求巷道
+                                    case "applyContinue": //表示手动调用请求巷道
                                         agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
                                         break;
 
+                                    case "applyContinueManaual": //表示请求巷道
+                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
+                                        agvTask.Status = AGVTaskStatus.Confirm;
+                                        break;
                                     case "applySecurity": //表示请求放货或取货
                                         agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission2;
                                         break;
 
+                                    case "end_1": //一楼出满任务完成
+                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                        break;
+
                                     case "hjend_2": //补空任务完成
                                         agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                         break;
@@ -254,7 +310,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                     default:
                                         break;
                                 }
-                                db.Default.Updateable(agvTask).SplitTable().ExecuteCommand();
+                                db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand();
                                 res.code = AgvResponseCode.Success;
                                 res.message = "成功";
                             }
@@ -267,7 +323,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                         res.code = AgvResponseCode.Error;
                         res.message = ex.Message;
                     }
-                }
+                //}
             }
             finally
             {

+ 27 - 10
WCS.WorkEngineering/WebApi/Controllers/IwmsApi.cs

@@ -40,8 +40,9 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="matFast">快投标记</param>
         /// <param name="gradeCode">质量等级</param>
         /// <param name="wetIntoBinCode">仓位号</param>
+        /// <param name="reqCode">请求编号</param>
         /// <returns></returns>
-        public static zhongTianIntoStockResponse 满轮出库(string matCode, string wbCode, string taskNo, string rfid, string matNo, bool isSurplus, bool isRework, bool matFast, string gradeCode, string wetIntoBinCode)
+        public static zhongTianIntoStockResponse 满轮出库(string matCode, string wbCode, string taskNo, string rfid, string matNo, bool isSurplus, bool isRework, bool matFast, string gradeCode, string wetIntoBinCode, string reqCode, bool wetIntoNoRequest = false)
         {
             var zhongTian = new zhongTianIntoStockRequest()
             {
@@ -60,21 +61,36 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                 taskNo = $"RK{taskNo}",
                 returnDesc = "",
                 lockFlag = "0",
+                reqCode = reqCode,
             };
-            if (wetIntoBinCode.Length == 14)
+            if (wetIntoNoRequest == true)
             {
-                zhongTian.wetInto = true;
-                zhongTian.wetIntoBinCode = wetIntoBinCode;
+                //zhongTian.wetInto = true;
+                zhongTian.wetIntoBinCode = "";
+
+                zhongTian.wetIntoNoRequest = true;
                 zhongTian.wetIntoSpec = false;
                 zhongTian.wetSpecWbCode = "";
+                zhongTian.matNo = matNo;
             }
             else
             {
-                zhongTian.wetInto = false;
-                zhongTian.wetIntoBinCode = "";
-                zhongTian.wetIntoSpec = true;
-                zhongTian.wetSpecWbCode = wetIntoBinCode;
+                if (wetIntoBinCode.Length == 14)
+                {
+                    zhongTian.wetInto = true;
+                    zhongTian.wetIntoBinCode = wetIntoBinCode;
+                    zhongTian.wetIntoSpec = false;
+                    zhongTian.wetSpecWbCode = "";
+                }
+                else
+                {
+                    zhongTian.wetInto = false;
+                    zhongTian.wetIntoBinCode = "";
+                    zhongTian.wetIntoSpec = true;
+                    zhongTian.wetSpecWbCode = wetIntoBinCode;
+                }
             }
+         
             return zhongTianIntoStock(zhongTian);
             //return zhongTianOutStock(new zhongTianOutStockRequest()
             //{
@@ -84,7 +100,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             //});
         }
 
-        public static zhongTianOutStockResponse 空轮回库(string matCode, string wbCode, bool isSurplus, bool isRework, int taskNo, string RFID)
+        public static zhongTianOutStockResponse 空轮回库(string matCode, string wbCode, bool isSurplus, bool isRework, int taskNo, string RFID, string reqCode)
         {
             return zhongTianOutStock(new zhongTianOutStockRequest()
             {
@@ -97,7 +113,8 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                 spoolNo = RFID,
                 isSurplus = isSurplus == false ? "0" : "1",
                 isRework = isRework == false ? "0" : "1",
-                reqCode = Guid.NewGuid().ToString().Replace("-", ""),
+                //reqCode = Guid.NewGuid().ToString().Replace("-", ""),
+                reqCode = reqCode,
                 taskNo = $"CK{wbCode}{taskNo}"
             });
         }

+ 155 - 11
WCS.WorkEngineering/WebApi/Controllers/WcsController.cs

@@ -7,6 +7,7 @@ using ServiceCenter.Extensions;
 using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using ServiceCenter.SqlSugars;
+using System;
 using System.Net.NetworkInformation;
 using System.Text;
 using WCS.Core;
@@ -133,21 +134,45 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                             var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First();
                             if (agv != null)
                             {
-                                if (!agv.AgvID.IsNullOrEmpty())
-                                {
-                                    var cancelTaskUpdateRes = CancelAgvTask(response, item, agv.AgvID);
-                                    //if (cancelTaskUpdateRes == null) continue;
-                                }
+                                //if (!agv.AgvID.IsNullOrEmpty())
+                                //{
+                                    
+                                   ;
+                                //}
                                 agv.Status = AGVTaskStatus.Cancel;
                                 agv.AgvStatus = AGVTaskStatus.Cancel;
-                                db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
+                            }
+                            if (task.Floor == 2)//二楼调用海康一键抹除
+                            {
+                                var cancelTaskUpdateRes = DelAgvTask(response, item, agv != null ? agv.AgvID : "", task.AddWho != "wms" && !string.IsNullOrEmpty(task.AddWho) ? task.AddWho : "");
+                                if (response.ResDataList != null && response.ResDataList.Any())
+                                {
+                                    if (response.ResDataList.FirstOrDefault().Message.Length > 200)
+                                    {
+                                        task.AddWCS_TASK_DTL(db, "一键抹除", response.ResDataList.FirstOrDefault().Message.Substring(0, 200));
+                                    }
+                                    else
+                                    {
+                                        task.AddWCS_TASK_DTL(db, "一键抹除", response.ResDataList.FirstOrDefault().Message);
+                                    }
+
+                                }
+
                             }
+                            else
+                            {
+                                var cancelTaskUpdateRes = CancelAgvTask(response, item, agv != null ? agv.AgvID : "");
+                                //if (cancelTaskUpdateRes == null) continue;
+                            }
+
                             //更新任务状态
                             task.Status = Entity.TaskStatus.Cancel;
                             task.EedTime = DateTime.Now;
                             task.EditWho = req.User;
                             task.ManualRemarks = req.ManualRemarks;
                             task.AddWCS_TASK_DTL(db, "未知", "任务取消");
+                       
                             db.Default.Updateable(task).ExecuteCommand();
                             task.CompleteOrCancelTasks(db);
                         }
@@ -197,10 +222,13 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                 SRes cancelRes = CarryTaskInfo(response, item, 99);
                                 if (cancelRes == null) continue;
 
+                               
+
                                 //找到对应的AGV任务
                                 var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First();
                                 if (agv != null)
                                 {
+                                   
                                     //if (!agv.AgvID.IsNullOrEmpty())
                                     //{
                                     //    var cancelTaskUpdateRes = CancelAgvTask(response, item, agv.AgvID);
@@ -208,8 +236,31 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                     //}
                                     agv.Status = AGVTaskStatus.MissionCompleted;
                                     agv.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
+                                }
+                                if (task.Floor == 2)//二楼调用海康一键抹除
+                                {
+                                    var cancelTaskUpdateRes = DelAgvTask(response, item, agv != null ? agv.AgvID : "", task.AddWho != "wms" && !string.IsNullOrEmpty(task.AddWho) ? task.AddWho : "");
+                                    if (response.ResDataList != null && response.ResDataList.Any())
+                                    {
+                                        if (response.ResDataList.FirstOrDefault().Message.Length > 200)
+                                        {
+                                            task.AddWCS_TASK_DTL(db, "一键抹除", response.ResDataList.FirstOrDefault().Message.Substring(0, 200));
+                                        }
+                                        else
+                                        {
+                                            task.AddWCS_TASK_DTL(db, "一键抹除", response.ResDataList.FirstOrDefault().Message);
+                                        }
+
+                                    }
+
+                                }
+                                else
+                                {
+                                    //var cancelTaskUpdateRes = CancelAgvTask(response, item, agv != null ? agv.AgvID : "");
+                                    //if (cancelTaskUpdateRes == null) continue;
                                 }
+                                    ;
                                 //更新任务状态
                                 task.Status = Entity.TaskStatus.Finish;
                                 task.EedTime = DateTime.Now;
@@ -237,7 +288,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                             });
                                             continue;
                                         }
-                                        if (task.AddrTo.Length < 6)
+                                        if (task.AddrTo.Length < 6 && task.TaskGroupKey != "1")
                                         {
                                             response.ResDataList.Add(new HandleTaskResponse()
                                             {
@@ -247,7 +298,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                             });
                                             continue;
                                         }
-                                        break;                                                                            
+                                        break;
                                 }
 
                                 SRes cancelRes = CarryTaskInfo(response, item, 99);
@@ -264,7 +315,68 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                     //}
                                     agv.Status = AGVTaskStatus.MissionCompleted;
                                     agv.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
+                                }
+                                //更新任务状态
+                                task.Status = Entity.TaskStatus.Finish;
+                                task.EedTime = DateTime.Now;
+                                task.EditWho = req.User;
+                                task.ManualRemarks = req.ManualRemarks;
+                                task.AddWCS_TASK_DTL(db, "未知", "任务完成");
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.CompleteOrCancelTasks(db);
+                            }
+                            else if (task.Type == TaskType.TransferDepot)
+                            {
+                                SRes res = HandleTaskVerify(response, item, 99);
+                                if (res == null) continue;
+
+                                switch (task.Type)
+                                {
+                                    case TaskType.TransferDepot:
+                                        //if (task.Status >= Entity.TaskStatus.Finish)
+                                        //{
+                                        //    response.ResDataList.Add(new HandleTaskResponse()
+                                        //    {
+                                        //        IsSuccess = false,
+                                        //        TaskNo = item,
+                                        //        Message = $"只能完成未完成状态的任务",
+                                        //    });
+                                        //    continue;
+                                        //}
+                                        if (task.AddrTo.Length < 6)
+                                        {
+                                            response.ResDataList.Add(new HandleTaskResponse()
+                                            {
+                                                IsSuccess = false,
+                                                TaskNo = item,
+                                                Message = $"只能完成已分配货位的任务",
+                                            });
+                                            continue;
+                                        }
+                                        break;
+                                }
+                                SRes cancelRes = CarryTaskInfo(response, item, 99);
+                                if (cancelRes == null) continue;
+
+                                //更新任务状态
+                                task.Status = Entity.TaskStatus.Finish;
+                                task.EedTime = DateTime.Now;
+                                task.EditWho = req.User;
+                                task.ManualRemarks = req.ManualRemarks;
+                                task.AddWCS_TASK_DTL(db, "未知", "任务完成");
+                                db.Default.Updateable(task).ExecuteCommand();
+                                task.CompleteOrCancelTasks(db);
+                            }
+                            else if (task.Type == TaskType.Delivery)
+                            {
+                                //找到对应的AGV任务
+                                var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First();
+                                if (agv != null)
+                                {                                  
+                                    agv.Status = AGVTaskStatus.MissionCompleted;
+                                    agv.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                    db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                                 }
                                 //更新任务状态
                                 task.Status = Entity.TaskStatus.Finish;
@@ -369,7 +481,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                             {
                                 agv.Status = AGVTaskStatus.NewBuild;
                                 agv.AgvStatus = AGVTaskStatus.NewBuild;
-                                db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
                             }
                             if (task.Floor == 1)
                             {
@@ -405,6 +517,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="id"></param>
         /// <param name="agvTask">需要取消任务的AGV任务号</param>
         /// <returns></returns>
+        [HttpGet]
         public CancelTaskResponse? CancelAgvTask(SRes<HandleTaskResponse> sRes, int id, string agvTask)
         {
             try
@@ -423,6 +536,33 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                 return null;
             }
         }
+        /// <summary>
+        ///  一键抹除海康任务
+        /// </summary>
+        /// <param name="sRes"></param>
+        /// <param name="id"></param>
+        /// <param name="agvTask">需要取消任务的AGV任务号</param>
+        /// <param name="reqCode">请求编号</param>
+        /// <returns></returns>
+        [HttpGet]
+        public CancelTaskResponse? DelAgvTask(SRes<HandleTaskResponse> sRes, int id, string agvTask, string reqCode)
+        {
+            try
+            {
+                var res = AgvApi.DelAgvTask(agvTask, reqCode);
+                return res;
+            }
+            catch (Exception ex)
+            {
+                sRes.ResDataList.Add(new HandleTaskResponse()
+                {
+                    IsSuccess = false,
+                    TaskNo = id,
+                    Message = $"AGV错误:{ex.Message}",
+                });
+                return null;
+            }
+        }
 
         /// <summary>
         ///  WMS完成或取消任务验证
@@ -431,6 +571,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="id"></param>
         /// <param name="type">99完成,106取消</param>
         /// <returns></returns>
+        [HttpGet]
         public SRes? HandleTaskVerify(SRes<HandleTaskResponse> sRes, int id, int type)
         {
             try
@@ -457,6 +598,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="id"></param>
         /// <param name="type">99完成,106取消</param>
         /// <returns></returns>
+        [HttpGet]
         public SRes? CarryTaskInfo(SRes<HandleTaskResponse> sRes, int id, int type)
         {
             try
@@ -483,6 +625,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="id"></param>
         /// <param name="type"></param>
         /// <returns></returns>
+        [HttpGet]
         public SRes? CancelAgvTaskUpdate(SRes<HandleTaskResponse> sRes, int id, int type)
         {
             try
@@ -633,6 +776,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// </summary>
         /// <param name="strIpOrDName">输入参数,表示IP地址或域名</param>
         /// <returns></returns>
+        [HttpGet]
         public static bool PingIpOrDomainName(string strIpOrDName)
         {
             try

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

@@ -175,6 +175,9 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                 case "1016":
                     request.Tunnel = "3";
                     break;
+                case "1118" or "1131" or "1132" or "1133" or "1134" or "1135" or "1136" or "1137" or "1139":
+                    request.Tunnel = "4";
+                    break;
             }
             var res = APICaller.CallApi2<SRes>(WMSUrl + "/api/Hj/ApplyStockOutTask", request);
             if (res.ResCode != ResponseStatusCodeEnum.Sucess)

+ 23 - 0
WCS.WorkEngineering/WebApi/Models/AGV/Request/CancelTaskRequest.cs

@@ -47,4 +47,27 @@
         /// </summary>
         public string taskCode { get; set; }
     }
+
+    /// <summary>
+    ///  取消任务
+    /// </summary>
+    public class DelTaskRequest
+    {
+        /// <summary>
+        ///  请求编号
+        /// </summary>
+        public string reqCode { get; set; }
+
+
+
+        /// <summary>
+        /// 任务单编号, 取消该任务单
+        /// </summary>
+        public string cleanTaskCode { get; set; }
+
+        /// <summary>
+        /// 取消的请求编号
+        /// </summary>
+        public string cancelReqCode { get; set; }
+    }
 }

+ 112 - 0
WCS.WorkEngineering/WebApi/Models/AGV/Request/GenAgvSchedulingTaskRequest.cs

@@ -115,6 +115,118 @@
         /// </summary>
         public string data { get; set; }
     }
+    public class GenAgvSchedulingTaskRequest2
+    {
+        /// <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 int ctnrTyp { get; set; }
+
+        /// <summary>
+        ///  RFID
+        /// </summary>
+        public string ctnrCode { get; set; }
+
+        /// <summary>
+        /// 接口名称
+        /// </summary>
+        public string interfaceName { get; set; }
+
+        /// <summary>
+        /// 任务模式
+        /// </summary>
+        public string taskMode { get; set; }
+
+        /// <summary>
+        ///  合金任务模板
+        /// </summary>
+        public string hjTaskTy { get; set; }
+
+        /// <summary>
+        /// 工作位
+        /// </summary>
+        public string wbCode { get; set; }
+
+        /// <summary>
+        /// 位置路径
+        /// </summary>
+        public List<positionCodeClass> positionCodePath { get; set; }
+
+        /// <summary>
+        ///  位置类型
+        /// </summary>
+        public string type { 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格式
+        /// </summary>
+        public string data { get; set; }
+    }
 
     /// <summary>
     ///  AGV生成任务单请求TaskTyp对应枚举

+ 6 - 0
WCS.WorkEngineering/WebApi/Models/AGV/Request/zhongTianIntoStockRequest.cs

@@ -99,5 +99,11 @@
         ///  仓位号
         /// </summary>
         public string wetIntoBinCode { get; set; }
+
+        public bool wetIntoNoRequest { get; set; }
+        /// <summary>
+        /// 请求编号
+        /// </summary>
+        public string reqCode { get; set; }
     }
 }

+ 47 - 21
WCS.WorkEngineering/WorkStart.cs

@@ -32,7 +32,8 @@ namespace WCS.WorkEngineering
 
             List<StationSegmentInfo> segmentInfo = new List<StationSegmentInfo>
             {
-                new StationSegmentInfo(1011, 1026, "10.30.36.51")
+                new StationSegmentInfo(1011, 1026, "10.30.36.51"),
+                new StationSegmentInfo(1117, 1139,"10.30.36.82")
             };
 
             foreach (var item in segmentInfo)
@@ -53,7 +54,8 @@ namespace WCS.WorkEngineering
 
             List<BcrInfo> bcrInfo = new List<BcrInfo>
             {
-                new BcrInfo(new int[] { 1011, 1013, 1015 }, "10.30.36.51")
+                new BcrInfo(new int[] { 1011, 1013, 1015}, "10.30.36.51"),
+                new BcrInfo(new int[] {1117,1138}, "10.30.36.82")
             };
 
             foreach (var item in bcrInfo)
@@ -73,7 +75,8 @@ namespace WCS.WorkEngineering
 
             List<ShapeInfo> shapeInfo = new List<ShapeInfo>
             {
-                new ShapeInfo(new int[] { 1011, 1013, 1015,1021,1023, 1025 }, "10.30.36.51")
+                new ShapeInfo(new int[] { 1011, 1013, 1015, 1021,1023, 1025, }, "10.30.36.51"),
+                new ShapeInfo(new int[] { 1117,1127,1138}, "10.30.36.82")
             };
 
             foreach (var item in shapeInfo)
@@ -93,15 +96,24 @@ namespace WCS.WorkEngineering
 
             #region 初始化堆垛机相关信息
 
-            for (int i = 2; i <= 3; i++)
+            for (int i = 1; i <= 4; i++)
             {
                 var srm = new Device($"SRM{i}");
                 srm.AddFlag(DeviceFlags.堆垛机);
 
                 //三台堆垛机IP主机位分别是 21 31 41
-                srm.AddProtocol<ISRM520>(0, 520, $"10.30.36.{(i * 10) + 10 + 1}");
-                srm.AddProtocol<ISRM521>(0, 521, $"10.30.36.{(i * 10) + 10 + 1}");
-                srm.AddProtocol<ISRM537>(0, 537, $"10.30.36.{(i * 10) + 10 + 1}");
+                if (i == 4)
+                {
+                    srm.AddProtocol<ISRM520>(0, 520, $"10.30.36.71");
+                    srm.AddProtocol<ISRM521>(0, 521, $"10.30.36.71");
+                    srm.AddProtocol<ISRM537>(0, 537, $"10.30.36.71");
+                }
+                else {
+                    srm.AddProtocol<ISRM520>(0, 520, $"10.30.36.{(i * 10) + 10 + 1}");
+                    srm.AddProtocol<ISRM521>(0, 521, $"10.30.36.{(i * 10) + 10 + 1}");
+                    srm.AddProtocol<ISRM537>(0, 537, $"10.30.36.{(i * 10) + 10 + 1}");
+                }
+                
 
                 //增加巷道
                 var tunnel = new Device($"TY{i}");
@@ -114,21 +126,35 @@ namespace WCS.WorkEngineering
 
             List<RouteInfo> routeInfos = new List<RouteInfo>
             {
-                //new RouteInfo("SRM1", new string[] { "TY1" }),
+                new RouteInfo("SRM1", new string[] { "TY1" }),
                 new RouteInfo("SRM2", new string[] { "TY2" }),
                 new RouteInfo("SRM3", new string[] { "TY3" }),
-                //new RouteInfo("TY1", new string[] { "SRM1" }),
+                new RouteInfo("SRM4", new string[] { "TY4" }),
+                new RouteInfo("TY1", new string[] { "SRM1" }),
                 new RouteInfo("TY2", new string[] { "SRM2" }),
                 new RouteInfo("TY3", new string[] { "SRM3" }),
-                //new RouteInfo("TY1", new string[] { "1011", "1021" }),
+                new RouteInfo("TY4", new string[] { "SRM4" }),
+                new RouteInfo("TY1", new string[] { "1011", "1021" }),
                 new RouteInfo("TY2", new string[] { "1013", "1023" }),
                 new RouteInfo("TY3", new string[] { "1015", "1025" }),
-                //new RouteInfo("1012", new string[] { "TY1" }),
-                //new RouteInfo("1022", new string[] { "TY1" }),
+                new RouteInfo("TY4", new string[] { "1117", "1127", "1138"}),
+                new RouteInfo("1012", new string[] { "TY1" }),
+                new RouteInfo("1022", new string[] { "TY1" }),
                 new RouteInfo("1014", new string[] { "TY2" }),
                 new RouteInfo("1024", new string[] { "TY2" }),
                 new RouteInfo("1016", new string[] { "TY3" }),
-                new RouteInfo("1026", new string[] { "TY3" })
+                new RouteInfo("1026", new string[] { "TY3" }),
+                new RouteInfo("1118", new string[] { "TY4" }),
+                new RouteInfo("1128", new string[] { "TY4" }),
+                //侧边
+                new RouteInfo("1131", new string[] { "TY4" }),
+                new RouteInfo("1132", new string[] { "TY4" }),
+                new RouteInfo("1133", new string[] { "TY4" }),
+                new RouteInfo("1134", new string[] { "TY4" }),
+                new RouteInfo("1135", new string[] { "TY4" }),
+                new RouteInfo("1136", new string[] { "TY4" }),
+                new RouteInfo("1137", new string[] { "TY4" }),
+                new RouteInfo("1139", new string[] { "TY4" }),
             };
 
             foreach (var item in routeInfos)
@@ -150,14 +176,14 @@ namespace WCS.WorkEngineering
             Dictionary<DeviceFlags, List<string>> devices = new Dictionary<DeviceFlags, List<string>>
             {
                 { DeviceFlags.巷道口, new List<string>() { "1011", "1012", "1013", "1014", "1015", "1016", "1021", "1022", "1023", "1024", "1025", "1026" } },
-                { DeviceFlags.入库, new List<string>() { "1011", "1013", "1015", "1021", "1023", "1025" } },
-                { DeviceFlags.出库, new List<string>() { "1012", "1014", "1016", "1022", "1024", "1026" } },
-                { DeviceFlags.扫码, new List<string>() { "1011", "1013", "1015" } },
-                { DeviceFlags.一楼出库口, new List<string>() { "1012", "1014", "1016" } },
-                { DeviceFlags.二楼出库口, new List<string>() { "1022", "1024", "1026" } },
-                { DeviceFlags.一楼入库口, new List<string>() { "1011", "1013", "1015" } },
-                { DeviceFlags.二楼入库口, new List<string>() { "1021", "1023", "1025" } },
-                { DeviceFlags.称重, new List<string>() { "1011", "1013", "1015", "1025" } }
+                { DeviceFlags.入库, new List<string>() { "1011", "1013", "1015", "1117", "1021", "1023", "1025", "1127" } },
+                { DeviceFlags.出库, new List<string>() { "1012", "1014", "1016", "1118", "1022", "1024", "1026", "1128" } },
+                { DeviceFlags.扫码, new List<string>() { "1011", "1013", "1015" , "1117" ,"1139"} },
+                { DeviceFlags.一楼出库口, new List<string>() { "1012", "1014", "1016" ,"1118", "1131", "1132", "1133", "1134", "1135", "1136", "1137", "1139" } },
+                { DeviceFlags.二楼出库口, new List<string>() { "1022", "1024", "1026", "1128" } },
+                { DeviceFlags.一楼入库口, new List<string>() { "1011", "1013", "1015", "1117","1138"} },
+                { DeviceFlags.二楼入库口, new List<string>() { "1021", "1023", "1025", "1127" } },
+                { DeviceFlags.称重, new List<string>() { "1011", "1013", "1015","1117", "1025", "1127","1138" } }
             };
 
             devices.ForEach(item =>