Ver Fonte

盘条代码

xu.lu há 2 anos atrás
pai
commit
9d0908eba9
23 ficheiros alterados com 1101 adições e 163 exclusões
  1. 3 16
      合金库/WCS.WorkEngineering/Systems/AgvSystems.cs
  2. 1 0
      合金库/WCS.WorkEngineering/Systems/一楼入库工位处理系统.cs
  3. 0 1
      合金库/WCS.WorkEngineering/Systems/二楼出库工位处理系统.cs
  4. 1 1
      合金库/WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs
  5. 263 0
      合金库/WCS.WorkEngineering/WebApi/Controllers/AgvController.cs
  6. 3 3
      盘条库/WCS.WorkEngineering/Extensions/DeviceExtension.cs
  7. 4 4
      盘条库/WCS.WorkEngineering/Extensions/StationExtension.cs
  8. 6 0
      盘条库/WCS.WorkEngineering/Protocol/Station/StationEnum.cs
  9. 140 3
      盘条库/WCS.WorkEngineering/Systems/AgvSystems.cs
  10. 129 2
      盘条库/WCS.WorkEngineering/Systems/NoInteractionSystems.cs
  11. 3 8
      盘条库/WCS.WorkEngineering/Systems/SrmSystems.cs
  12. 26 37
      盘条库/WCS.WorkEngineering/Systems/一楼入库工位处理系统.cs
  13. 129 0
      盘条库/WCS.WorkEngineering/Systems/一楼入库巷道分配处理系统.cs
  14. 14 30
      盘条库/WCS.WorkEngineering/Systems/一楼出库工位处理系统.cs
  15. 67 0
      盘条库/WCS.WorkEngineering/Systems/出入库站台处理系统.cs
  16. 185 0
      盘条库/WCS.WorkEngineering/Systems/货架调度处理系统.cs
  17. 1 0
      盘条库/WCS.WorkEngineering/WCS.WorkEngineering.csproj
  18. 2 2
      盘条库/WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs
  19. 28 28
      盘条库/WCS.WorkEngineering/WebApi/Controllers/AgvController.cs
  20. 1 13
      盘条库/WCS.WorkEngineering/WebApi/Controllers/WcsController.cs
  21. 22 1
      盘条库/WCS.WorkEngineering/WebApi/Controllers/WmsApi.cs
  22. 21 0
      盘条库/WCS.WorkEngineering/WebApi/Models/WMS/Request/PinKuCarryInTaskRequest.cs
  23. 52 14
      盘条库/WCS.WorkEngineering/WorkStart.cs

+ 3 - 16
合金库/WCS.WorkEngineering/Systems/AgvSystems.cs

@@ -75,6 +75,8 @@ namespace WCS.WorkEngineering.Systems
                                     db.Default.Updateable(taskInfo).ExecuteCommand();
                                     taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
                                     taskInfo.CompleteOrCancelTasks(db);
+
+                                    //通知WMS
                                     taskInfos.Add(taskInfo);
                                 }
                                 catch (Exception ex)
@@ -197,22 +199,7 @@ namespace WCS.WorkEngineering.Systems
                         //放货站点安全交互
                         else if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
                         {
-                            var dev = devs.Find(v => v.Entity.Code == agv.Position);
-                            //var srmNo = "";
-                            //if (dev.Entity.Code is "1011" or "1021") srmNo = "SRM1";
-                            //else if (dev.Entity.Code is "1013" or "1023") srmNo = "SRM2";
-                            //else if (dev.Entity.Code is "1015" or "1025") srmNo = "SRM3";
-                            //else
-                            //{
-                            //    World.Log($"未找到对应的堆垛机", LogLevelEnum.Mid);
-                            //    continue;
-                            //}
-                            //var srm = srms.FirstOrDefault(v => v.Entity.Code == srmNo);
-                            //if (!srm.Data2.Status.HasFlag(SrmStatus.ForkCenter))
-                            //{
-                            //    World.Log($"{srmNo}", LogLevelEnum.Mid);
-                            //    continue;
-                            //}
+                            var dev = devs.Find(v => v.Entity.Code == agv.Position);                            
 
                             if (dev.Data.VoucherNo != dev.Data2.VoucherNo)
                             {

+ 1 - 0
合金库/WCS.WorkEngineering/Systems/一楼入库工位处理系统.cs

@@ -41,6 +41,7 @@ namespace WCS.WorkEngineering.Systems
                 SqlSugarHelper.Do(_db =>
                 {
                     var db = _db.Default;
+
                     //获取RFID
                     var barcode = BCRS.GetBCRCode(obj.Entity.Code);
                     //跟据RFID获取对应的任务

+ 0 - 1
合金库/WCS.WorkEngineering/Systems/二楼出库工位处理系统.cs

@@ -38,7 +38,6 @@ namespace WCS.WorkEngineering.Systems
                 task.AddWCS_TASK_DTL(db, obj.Entity.Code, "AGV", $"任务已下发AGV,AGVID:{agv.AgvID}");
             });
         }
-
         public override bool Select(Device dev)
         {
             //return dev.Code == "1026";

+ 1 - 1
合金库/WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs

@@ -40,7 +40,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="taskCode">WMS任务号</param>
         /// <param name="priority">优先级</param>
         /// <returns></returns>
-        public static GenAgvSchedulingTaskResponse 满轮入库(string ctnrCode, string position, string taskCode, string priority)
+        public static GenAgvSchedulingTaskResponse 盘条入库(string ctnrCode, string position, string taskCode, string priority)
         {
             return GenAgvSchedulingTask("iwms_third", ctnrCode, "4", new List<positionCodeClass>()
             {

+ 263 - 0
合金库/WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -2,6 +2,7 @@
 using Newtonsoft.Json;
 using PlcSiemens.Core.Extension;
 using ServiceCenter.Logs;
+using ServiceCenter.Redis;
 using ServiceCenter.SqlSugars;
 using WCS.Core;
 using WCS.Entity;
@@ -259,4 +260,266 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             }
         }
     }
+
+
+
+    /// <summary>
+    /// AGV相关接口控制器
+    /// </summary>
+    [ApiController]
+    [Route("api/[controller]/[action]")]
+    public class AgvController : ControllerBase
+    {
+        /// <summary>
+        ///  AGV任务下发测试
+        /// </summary>
+        /// <param name="type">任务类型</param>
+        /// <param name="code">RFID</param>
+        /// <param name="pos">目标位置</param>
+        /// <returns></returns>
+        [HttpPost]
+        public string AgvDebug(int type, string code, string pos)
+        {
+            try
+            {
+                switch (type)
+                {
+                    case 1:
+                        AgvApi.机台补空(pos, code, "1");
+                        break;
+
+                    case 2:
+                        //AgvApi.机台补满();
+                        break;
+
+                    case 3:
+                        AgvApi.满轮入库(code, pos, Guid.NewGuid().ToString().Replace("-", ""), "1");
+                        break;
+
+                    default:
+                        break;
+                }
+                return "成功";
+            }
+            catch (Exception ex)
+            {
+                return $"Error-----" +
+                      $"{ex.Message}------" +
+                      $"{ex.StackTrace}";
+            }
+        }
+
+        /// <summary>
+        ///  背负式AGV请求出库任务
+        /// </summary>
+        /// <param name="reqDto">请求参数</param>
+        /// <returns></returns>
+        [HttpPost]
+        public ApplyEmptySpoolResponse ApplyEmptySpool([FromBody] AgvFillEmptySpaceRequest reqDto)
+        {
+            var key = $"WCS:Lock:AGV:{nameof(ApplyEmptySpool)}";
+            ApplyEmptySpoolResponse agvFill = new ApplyEmptySpoolResponse();
+            try
+            {
+                if (RedisHub.Default.Get(key) != null)
+                {
+                    agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
+                    agvFill.ResMsg = $"[{nameof(ApplyEmptySpool)}]--触发并发管控";
+                }
+                else
+                {
+                    RedisHub.Default.Set(key, nameof(ApplyEmptySpool));
+                    LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"传入参数--{JsonConvert.SerializeObject(reqDto)}");
+
+                    try
+                    {
+                        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>;
+
+                        // 检测三个站台是否有货
+                        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 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();
+                            obj = obj.Where(v => !agvStations.Contains(v.Entity.Code)).ToList();
+                            if (!obj.Any())
+                            {
+                                agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
+                                agvFill.ResMsg = "无可用取货站点";
+                                return;
+                            }
+
+                            foreach (var item in res.ResDataList)
+                            {
+                                var station = Device.All.Where(v => v.Code == "TY" + item.Tunnel.ToString())
+                                                        .Select(v => v.Targets).SelectMany(v => v)
+                                                        .Where(v => v.HasProtocol(typeof(IStation520)))
+                                                        .Where(v => v.Code is "1012" or "1014" or "1016")
+                                                        .FirstOrDefault();
+                                item.Tunnel = station.ToInt();
+                            }
+                            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("无有效任务");
+                            var id = db.GetAGVTaskId();
+                            var agv = new WCS_AgvTaskInfo()
+                            {
+                                ID = id,
+                                AgvID = $"HJBK{id}{task.ID}",
+                                TaskType = AGVTaskType.CallForMaterial,
+                                Status = AGVTaskStatus.NewBuild,
+                                Station = dev.Entity.Code,
+                                AddWho = "WCS"
+                            };
+                            //创建对应的AGV任务
+                            db.Default.Insertable(agv).SplitTable().ExecuteCommand();
+
+                            task.AgvTaskID = agv.ID;
+                            task.Status = Entity.TaskStatus.AGVExecution;
+                            db.Default.Updateable(task).ExecuteCommand();
+                            task.AddWCS_TASK_DTL(db, dev.Entity.Code, "AGV", "agv执行中");
+
+                            agvFill.LocCode = dev.Entity.Code;
+                            agvFill.SpoolType = "4";
+                            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)}");
+                }
+            }
+            finally
+            {
+                RedisHub.Default.Del(key);
+            }
+            return agvFill;
+        }
+
+        /// <summary>
+        /// AGV执行回调
+        /// </summary>
+        /// <param name="reqDto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public AgvCallbackResponse AgvCallback([FromBody] AgvCallbackRequest reqDto)
+        {
+            var key = $"WCS:Lock:AGV:{nameof(AgvCallback)}";
+            var res = new AgvCallbackResponse() { code = AgvResponseCode.Fail, message = "失败" };
+            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);
+                            if (agvTask == null)
+                            {
+                                res.code = AgvResponseCode.Fail;
+                                res.message = "未找到对应的AGV任务";
+
+                            }
+                            else
+                            {
+                                switch (reqDto.method)
+                                {
+                                    //case "start": //表示请求巷道
+                                    //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
+                                    //    break;
+
+                                    //case "end": //表示请求巷道
+                                    //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
+                                    //    break;
+
+                                    case "applyContinue": //表示请求巷道
+                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
+                                        break;
+
+                                    case "applySecurity": //表示请求放货或取货
+                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission2;
+                                        break;
+
+                                    case "hjend_2": //补空任务完成
+                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                        break;
+
+                                    case "endhjBM": //取满任务完成
+                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                        break;
+
+                                    case "end": //二楼出满任务完成
+                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                        break;
+
+                                    case "tcEnd": //机台补空任务完成
+                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                        break;
+
+                                    case "exc_end": //异常信息上抛-值不匹配
+                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                                        break;
+
+                                    case "outbin": //小车退出取货位
+                                        agvTask.AgvStatus = AGVTaskStatus.Complete3;
+                                        break;
+
+                                    case "cancel": //取消任务
+                                                   //agvTask.AgvStatus = AGVTaskStatus.Cancel;
+                                        break;
+
+                                    default:
+                                        break;
+                                }
+                                db.Default.Updateable(agvTask).SplitTable().ExecuteCommand();
+                                res.code = AgvResponseCode.Success;
+                                res.message = "成功";
+                            }
+
+
+                        });
+                    }
+                    catch (Exception ex)
+                    {
+                        res.code = AgvResponseCode.Error;
+                        res.message = ex.Message;
+                    }
+                }
+            }
+            finally
+            {
+                RedisHub.Default.Del(key);
+            }
+            return res;
+        }
+    }
 }

+ 3 - 3
盘条库/WCS.WorkEngineering/Extensions/DeviceExtension.cs

@@ -97,7 +97,7 @@ namespace WCS.WorkEngineering.Extensions
         一楼出库口 = 1 << 17,
         二楼出库口 = 1 << 18,
         一楼入库口 = 1 << 19,
-        二楼入库口 = 1 << 20,
+        检测门 = 1 << 20,
 
         一楼出入库口 = 1 << 21,
         二楼出入库口 = 1 << 22,
@@ -109,8 +109,8 @@ namespace WCS.WorkEngineering.Extensions
 
         #endregion 一轨双车堆垛机
 
-        RGV = 1 << 25,
-        桁架 = 1 << 26
+        货架调度 = 1 << 25,
+        叫料站台 = 1 << 26
     }
 
     /// <summary>

+ 4 - 4
盘条库/WCS.WorkEngineering/Extensions/StationExtension.cs

@@ -17,9 +17,9 @@ namespace WCS.WorkEngineering.Extensions
         /// <returns></returns>
         public void 入库站点是否被禁止()
         {
-            var config = RedisHub.Default.Check("ForbidTubuEnter") ?? throw new Exception("请在Redis中配置入库口禁用");
+            var config = RedisHub.Default.Check("ForbidTubuEnter") ?? throw new Exception("请在Redis中配置检测门禁用");
             var configs = config.Split(",");
-            if (configs.Contains(Entity.Code)) throw new KnownException("当前入库口已被禁用,请联系运维人员了解具体情况", LogLevelEnum.High);
+            if (configs.Contains(Entity.Code)) throw new KnownException("当前检测门已被禁用,请联系运维人员了解具体情况", LogLevelEnum.High);
         }
 
         /// <summary>
@@ -30,8 +30,8 @@ namespace WCS.WorkEngineering.Extensions
         {
             if (Data.VoucherNo != Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{Data.VoucherNo}-DB521:{Data2.VoucherNo}", LogLevelEnum.High);
             if (Data3.Status.HasFlag(StationStatus.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
-            if (Data3.Status.HasFlag(StationStatus.PH_Status) && Data2.Request == 0) throw new KnownException("有光电无请求", LogLevelEnum.Mid);
-            if (!Data3.Status.HasFlag(StationStatus.PH_Status) && Data2.Request == 1) throw new KnownException("无光电有请求", LogLevelEnum.Mid);
+            //if (Data3.Status.HasFlag(StationStatus.PH_Status) && Data2.Request == 0) throw new KnownException("有光电无请求", LogLevelEnum.Mid);
+            //if (!Data3.Status.HasFlag(StationStatus.PH_Status) && Data2.Request == 1) throw new KnownException("无光电有请求", LogLevelEnum.Mid);
         }
     }
 }

+ 6 - 0
盘条库/WCS.WorkEngineering/Protocol/Station/StationEnum.cs

@@ -135,6 +135,12 @@ namespace WCS.WorkEngineering.Protocol.Station
         /// </summary>
         [Description("上位机未分配任务")]
         UnassignedTask = 1 << 15,
+
+        /// <summary>
+        /// 探货光电有货
+        /// </summary>
+        [Description("探货光电有货")]
+        PH_Status_1 = 1 << 16,
     }
 
     /// <summary>

+ 140 - 3
盘条库/WCS.WorkEngineering/Systems/AgvSystems.cs

@@ -1,7 +1,14 @@
-using System.ComponentModel;
+using PlcSiemens.Core.Extension;
+using ServiceCenter.Extensions;
+using ServiceCenter.Logs;
+using ServiceCenter.SqlSugars;
+using System.ComponentModel;
 using WCS.Core;
+using WCS.Entity;
 using WCS.WorkEngineering.Extensions;
 using WCS.WorkEngineering.Protocol.SRM;
+using WCS.WorkEngineering.Protocol.Station;
+using WCS.WorkEngineering.WebApi.Controllers;
 using WCS.WorkEngineering.Worlds;
 using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
 
@@ -26,11 +33,141 @@ namespace WCS.WorkEngineering.Systems
             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();
         }
-
         public override void Do(Station obj)
         {
-        }
+            if (obj.Entity.HasFlag(DeviceFlags.出库))
+            {
+                List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
+                //获取所有未结束的AGV任务
+                SqlSugarHelper.Do(db =>
+                {
+                    agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted)                                                                                                                                                 .SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.AddTime).ToList();
+                });
+                //有需要处理的AGV任务
+                if (agvTaskInfos.Any())
+                {
+                    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)
+                    {
+                        try
+                        {
+                            SqlSugarHelper.Do(db =>
+                            {
+                                //取货点安全交互
+                                if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
+                                {
+                                    var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
+                                    agv.Status = AGVTaskStatus.Complete2;
+                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    taskInfo.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}在站台{agv.Station}取货");
+                                    AgvApi.ContinueTask(agv.AgvID, agv.Station);
+                                }
+                                //完成任务
+                                else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
+                                {
+                                    if (agv.TaskType is AGVTaskType.CallForMaterial or AGVTaskType.ForkliftFilling or AGVTaskType.CallMaterial)
+                                    {
+                                        var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
+                                        if (taskInfo == null) throw new Exception($"未找到AGV任务{agv.ID}对应WCS任务");
+                                        //更新AGV任务状态
+                                        agv.Status = AGVTaskStatus.MissionCompleted;
+                                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                        //更新WCS任务状态
+                                        taskInfo.Status = Entity.TaskStatus.Finish;
+                                        taskInfo.EedTime = DateTime.Now;
+                                        db.Default.Updateable(taskInfo).ExecuteCommand();
+                                        taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
+                                        taskInfo.CompleteOrCancelTasks(db);
+                                        taskInfos.Add(taskInfo);
+                                    }
+                                    else
+                                    {
+                                        agv.Status = AGVTaskStatus.MissionCompleted;
+                                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    }
+                                }
+                            });
+                        }
+                        catch (Exception ex)
+                        {
+                            World.Log(ex.Message, LogLevelEnum.Mid);
+                            this.ExRecord(obj.Entity.Code, ex.Message);
+                            continue;
+                        }
+                    }
+
 
+                    foreach (var item in taskInfos)
+                    {
+                        WmsApi.CompleteTask(item.ID);
+                    }
+                }
+            }
+            else if (obj.Entity.HasFlag(DeviceFlags.入库))
+            {
+                List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
+                //获取所有未结束的入库AGV任务
+                SqlSugarHelper.Do(db =>
+                {
+                    agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot).SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.EditTime).ToList();
+                });
+
+                if (agvTaskInfos.Any())
+                {
+                    this.ExRecord(obj.Entity.Code, "可用入库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
+                    foreach (var agv in agvTaskInfos)
+                    {
+                        try
+                        {
+                            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任务");
+                                #region 开始跟据AGV状态做出处理                                
+                                //放货站点安全交互   
+                                if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
+                                {
+                                    if (agv.Position.IsNullOrEmpty()) throw new Exception($"无有效放货地址");
+                                    var dev = devs.Find(v => v.Entity.Code == agv.Position);
+                                    if (dev.Data.VoucherNo != dev.Data2.VoucherNo) throw new Exception($"AGV请求放货,但{dev.Entity.Code}凭证号不一致");
+                                    if (!dev.Data3.Status.HasFlag(StationStatus.Auto)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}不在自动状态");
+                                    if (dev.Data3.Status.HasFlag(StationStatus.PH_Status)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}光电有货");
+                                    if (dev.Data3.Status.HasFlag(StationStatus.OT_Status)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}任务有货");
+                                    if (dev.Data3.Status.HasFlag(StationStatus.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);
+                                    dev.Data.TaskNumber = task.ID;                                
+                                }
+                                //完成任务
+                                else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
+                                {
+                                    var dev = devs.Find(v => v.Entity.Code == agv.Position);
+                                    dev.Data.TaskNumber = task.ID;
+                                    dev.Data.VoucherNo++;
+
+                                    agv.Status = AGVTaskStatus.MissionCompleted;
+                                    db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                                    //通知wms入库任务放货完成
+                                }
+                                #endregion 开始跟据AGV状态做出处理
+                            });
+                        }
+                        catch (Exception ex)
+                        {
+                            World.Log(ex.Message, LogLevelEnum.Mid);
+                            this.ExRecord(obj.Entity.Code, ex.Message);
+                            continue;
+                        }
+                    }
+                }
+            }
+        }
         public override bool Select(Device dev)
         {
             return dev.Code is "1011" or "1012";

+ 129 - 2
盘条库/WCS.WorkEngineering/Systems/NoInteractionSystems.cs

@@ -1,6 +1,13 @@
-using System.ComponentModel;
+using PlcSiemens.Core.Extension;
+using ServiceCenter.Logs;
+using ServiceCenter.Redis;
+using ServiceCenter.SqlSugars;
+using System.ComponentModel;
 using WCS.Core;
+using WCS.Entity;
 using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.WebApi.Controllers;
+using WCS.WorkEngineering.WebApi.Models.AGV.Response;
 using WCS.WorkEngineering.Worlds;
 
 namespace WCS.WorkEngineering.Systems
@@ -22,11 +29,131 @@ namespace WCS.WorkEngineering.Systems
 
         public override void Do(Station obj)
         {
+            var key = $"WCS:Lock:无交互系统{obj.Entity.Code}";
+            try
+            {
+                if (RedisHub.Default.Get(key) != null)
+                {
+                    throw new KnownException($"[{obj.Entity.Code}]--触发并发管控", LogLevelEnum.High);
+                }
+                RedisHub.Default.Set(key, obj.Entity.Code);
+
+                #region 处理所有的新增任务
+
+                try
+                {
+                    List<WCS_TaskInfo> taskInfos = new List<WCS_TaskInfo>();
+                    SqlSugarHelper.Do(db =>
+                    {
+                        taskInfos = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.Status == Entity.TaskStatus.NewBuild).ToList();
+                    });
+                    if (taskInfos.Any())
+                    {
+                        foreach (var item in taskInfos)
+                        {
+                            try
+                            {
+                                SqlSugarHelper.Do(db =>
+                                {
+                                    var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item.ID).First() ?? throw new Exception($"未找到对应的WCS任务[{item.ID}]");
+                                    if (task.Type == TaskType.EnterDepot)
+                                    {
+                                        //创建AGV任务
+                                        var agvTask = new WCS_AgvTaskInfo()
+                                        {
+                                            ID = db.GetAGVTaskId(),
+                                            TaskType = AGVTaskType.EnterDepot,
+                                            Status = AGVTaskStatus.NewBuild,
+                                            Station = task.WorkBench,
+                                            AddWho = "WCS",
+                                            //Position = task.SrmStation
+                                        };
+                                        db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                                        //更新任务状态
+                                        task.Status = Entity.TaskStatus.WaitingToExecute;
+                                        task.AgvTaskID = agvTask.ID;
+                                        db.Default.Updateable(task).ExecuteCommand();
+                                        task.AddWCS_TASK_DTL(db, task.Device, $"初始化入库任务信息,并创建AGV任务中间表,AGV任务目标地址:{agvTask.Station}");
+                                    }
+                                    else if (task.Type == TaskType.OutDepot)
+                                    {
+                                        //创建AGV任务
+                                        var agvTask = new WCS_AgvTaskInfo()
+                                        {
+                                            ID = db.GetAGVTaskId(),
+                                            TaskType = AGVTaskType.CallMaterial,
+                                            Status = AGVTaskStatus.NewBuild,
+                                            Station = task.SrmStation,
+                                            AddWho = "WCS",                                        
+                                        };
+                                        db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                                        //更新任务状态
+                                        task.Status = Entity.TaskStatus.WaitingToExecute;
+                                        task.AgvTaskID = agvTask.ID;
+                                        db.Default.Updateable(task).ExecuteCommand();
+                                        task.AddWCS_TASK_DTL(db, task.Device, $"初始化叫料任务信息,并创建AGV任务中间表,AGV任务目标地址:{agvTask.Position}");
+                                    }
+                                });
+                            }
+                            catch (Exception ex)
+                            {
+                                World.Log(ex.Message, LogLevelEnum.Mid);
+                                continue;
+                            }
+                        }
+                    }
+                }
+                catch (Exception ex)
+                {
+                    World.Log(ex.Message, LogLevelEnum.Mid);
+                }
+
+                #endregion 处理所有的新增任务
+
+                #region 下发agv任务
+                SqlSugarHelper.Do(db =>
+                {
+                    var agvTasks = db.Default.Queryable<WCS_AgvTaskInfo>().Where(t => t.Status == AGVTaskStatus.NewBuild && t.TaskType == AGVTaskType.EnterDepot).SplitTable(v => v.Take(2)).ToList();
+
+                    if (agvTasks.Count > 0)
+                    {
+                        foreach (var agv in agvTasks)
+                        {
+                            //开始处理
+                            try
+                            {
+                                //获取对应wcs任务
+                                var wcs = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.AgvTaskID == agv.ID && t.Status == Entity.TaskStatus.WaitingToExecute).First();
+                                if (wcs == null) throw new Exception($"未找到对应的WCS任务");
+                                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();
+
+                                //更新WCS数据
+                                wcs.Status = Entity.TaskStatus.AGVExecution;
+                                db.Default.Updateable(wcs).ExecuteCommand();
+                                wcs.AddWCS_TASK_DTL(db, wcs.Device, $"任务下发至AGV-AGV任务ID{agv.AgvID}");
+                            }
+                            catch (Exception ex)
+                            {
+                                World.Log(ex.Message, LogLevelEnum.Mid);
+                                continue;
+                            }
+                        }
+                    }
+                });
+                #endregion
+            }
+            finally
+            {
+                RedisHub.Default.Del(key);
+            }
         }
 
         public override bool Select(Device dev)
         {
-            return dev.Code == "1011";
+            return dev.Code == "1001";
         }
     }
 }

+ 3 - 8
盘条库/WCS.WorkEngineering/Systems/SrmSystems.cs

@@ -125,13 +125,7 @@ namespace WCS.WorkEngineering.Systems
                             db.Default.Updateable(task).ExecuteCommand();
                             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, "空轮初始化任务结束");
-                            break;
+                        
                     }
 
                     if (task.Status >= TaskStatus.Finish) task.CompleteOrCancelTasks(db);
@@ -294,7 +288,8 @@ namespace WCS.WorkEngineering.Systems
                 if (!arrOut.Any()) throw new KnownException($"堆垛机{obj.Entity.Code}无放货路径点", LogLevelEnum.High);
 
                 //获取可以放货的设备集合
-                arrOut = arrOut.Where(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status) //无光电
+                arrOut = arrOut.Where(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) //有货架
+                                                && !v.Data3.Status.HasFlag(StationStatus.PH_Status_1)//货架无货
                                                 && !v.Data3.Status.HasFlag(StationStatus.Run) //未运行
                                                 && !v.Data3.Status.HasFlag(StationStatus.OT_Status) //无任务
                                                 && !v.Data3.Status.HasFlag(StationStatus.UnassignedTask) //未分配任务

+ 26 - 37
盘条库/WCS.WorkEngineering/Systems/一楼入库工位处理系统.cs

@@ -1,12 +1,17 @@
 using ServiceCenter.Logs;
 using ServiceCenter.SqlSugars;
+using System;
+using System.Collections.Generic;
 using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
 using WCS.Core;
 using WCS.Entity;
 using WCS.WorkEngineering.Extensions;
 using WCS.WorkEngineering.Protocol.BCR;
+using WCS.WorkEngineering.Protocol.SRM;
 using WCS.WorkEngineering.Protocol.Station;
-using WCS.WorkEngineering.WebApi.Controllers;
 using WCS.WorkEngineering.Worlds;
 using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
 
@@ -25,61 +30,45 @@ namespace WCS.WorkEngineering.Systems
 
         private List<BCR> BCRS = new List<BCR>();
 
+        private List<Station> devs = new List<Station>();
+        private List<SRM> srms = new List<SRM>();
+
         public 一楼入库工位处理系统()
         {
             BCRS = Device.All.Where(v => v.HasProtocol<IBCR81>()).Select(v => new BCR(v, World)).ToList();
+            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();
         }
 
         public override void Do(Station obj)
         {
             obj.入库站点是否被禁止();
-            obj.入库站点是否满足执行条件();
-
-            WCS_TaskInfo task = null;//处理完成的任务
+            obj.入库站点是否满足执行条件();            
+            WCS_TaskInfo taskInfo = null;
             try
             {
                 SqlSugarHelper.Do(_db =>
                 {
-                    var db = _db.Default;
-                    //获取RFID
-                    var barcode = BCRS.GetBCRCode(obj.Entity.Code);
-                    //跟据RFID获取对应的任务
-                    var 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;
-                        else throw new KnownException($"任务:{taskInfo.ID}不是AGV执行状态,请检查异常原因", LogLevelEnum.High);
-                    }
-
-                    if (!obj.Data3.Status.HasFlag(StationStatus.ManualStorage)) //不是手动入库
+                    var db = _db.Default;                  
+                    if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status) || !obj.Data3.Status.HasFlag(StationStatus.PH_Status_1))
+                        return;
+                    if (!obj.Data3.Status.HasFlag(StationStatus.OT_Status))
+                        return;
+                    taskInfo = db.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data2.TaskNumber && v.Status < Entity.TaskStatus.Finish).First();
+                    if(taskInfo == null) throw new KnownException($"未找到对应wcs任务{obj.Data2.TaskNumber}", LogLevelEnum.High);
+                    if (taskInfo.SrmStation == obj.Entity.Code && taskInfo.Status == Entity.TaskStatus.AGVExecution)
                     {
-                        //判断AGV任务目标地址是否是当前地址
-                        var agv = db.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).First(v => v.ID == taskInfo.AgvTaskID) ?? throw new KnownException($"任务{taskInfo.ID}未找到对应AGV任务", LogLevelEnum.Mid);
-                        if (taskInfo.AddrNext != obj.Entity.Code) throw new KnownException($"任务{taskInfo.ID}不是货架上的任务,请检查RFID是否正确", LogLevelEnum.Mid);
-                        if (agv.Position != obj.Entity.Code) throw new KnownException($"任务{taskInfo.ID}对应AGV任务目标地址不是当前站台", LogLevelEnum.Mid);
-                    }
-
-                    //获取称重
-                    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);
-                    //上抛重量
-                    try { WmsApi.WcsUploadInfo(taskInfo.ID, (decimal)taskInfo.Weight, taskInfo.BarCode); } catch (Exception ex) { World.Log(ex.Message, LogLevelEnum.Mid); }
-
-                    taskInfo.Status = Entity.TaskStatus.ConveyorExecution;
-                    db.Updateable(taskInfo).ExecuteCommand();
-                    taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, "SRM", $"状态更新为{Entity.TaskStatus.ConveyorExecution},等待分配货位后堆垛机进行取货");
-                    task = taskInfo;
+                        taskInfo.Status = Entity.TaskStatus.ConveyorExecution;
+                        taskInfo.EditTime = DateTime.Now;
+                        db.Updateable(taskInfo).ExecuteCommand();                        
+                    }                                                         
                 });
             }
             catch (Exception ex)
             {
                 throw new KnownException(ex.Message, LogLevelEnum.High);
-            }
-            obj.Data.TaskNumber = task.ID;
-            obj.Data.VoucherNo++;
+            }            
         }
-
         public override bool Select(Device dev)
         {
             return dev.HasFlag(DeviceFlags.一楼入库口);

+ 129 - 0
盘条库/WCS.WorkEngineering/Systems/一楼入库巷道分配处理系统.cs

@@ -0,0 +1,129 @@
+using ServiceCenter.Logs;
+using ServiceCenter.SqlSugars;
+using System.ComponentModel;
+using WCS.Core;
+using WCS.Entity;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Protocol.BCR;
+using WCS.WorkEngineering.Protocol.SRM;
+using WCS.WorkEngineering.Protocol.Station;
+using WCS.WorkEngineering.WebApi.Controllers;
+using WCS.WorkEngineering.Worlds;
+using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
+
+namespace WCS.WorkEngineering.Systems
+{
+    /// <summary>
+    ///  一楼入库巷道分配处理系统
+    /// </summary>
+    [BelongTo(typeof(MainWorld))]
+    [Description("一楼入库巷道分配处理系统")]
+    public class 一楼入库巷道分配处理系统 : DeviceSystem<Station>
+    {
+        protected override bool ParallelDo => true;
+
+        protected override bool SaveLogsToFile => true;
+
+        private List<BCR> BCRS = new List<BCR>();
+
+        private List<Station> devs = new List<Station>();
+        private List<SRM> srms = new List<SRM>();
+
+        public 一楼入库巷道分配处理系统()
+        {
+            BCRS = Device.All.Where(v => v.HasProtocol<IBCR81>()).Select(v => new BCR(v, World)).ToList();
+            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();
+        }
+
+        public override void Do(Station obj)
+        {
+            obj.入库站点是否被禁止();
+            obj.入库站点是否满足执行条件();
+
+            WCS_TaskInfo task = null;//处理完成的任务
+            WCS_TaskInfo taskInfo = null;
+            try
+            {
+                SqlSugarHelper.Do(_db =>
+                {
+                    var db = _db.Default;
+                    //获取RFID
+                    var barcode = BCRS.GetBCRCode(obj.Entity.Code);
+                    //根据agv任务找到对应wcs任务并赋值
+                    if (db.Queryable<WCS_AgvTaskInfo>().SplitTable().Count(v => v.Status == AGVTaskStatus.RequestOrPermission1 && v.AgvStatus != AGVTaskStatus.Complete1 && v.Position == obj.Entity.Code)>1)
+                    {
+                        throw new KnownException($"未分配巷道任务数异常,请检查现场情况", LogLevelEnum.High);
+                    }
+                    var agvTask = db.Queryable<WCS_AgvTaskInfo>().SplitTable().First(v => v.Status == AGVTaskStatus.RequestOrPermission1 && v.AgvStatus != AGVTaskStatus.Complete1 && v.Position == obj.Entity.Code);
+                    if (agvTask == null)
+                    {
+                        throw new KnownException($"未找到对应agv任务", LogLevelEnum.High);
+                    }                       
+                    else
+                    {
+                        taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTask.ID) ?? throw new KnownException($"未找到agv任务{agvTask.ID}对应WCS任务", LogLevelEnum.High);
+                    }
+                    taskInfo.BarCode = barcode;
+                              
+                    //分配巷道,agv目标站台
+                    var res = WmsApi.GetTunnelPriorityList(taskInfo.ID);
+                    var tunnelNo = res.ResData.Split(",").Select(v => "TY" + v).ToList();            
+                    //开始获取堆垛机与可用站台信息
+                    SRM srm = null;
+                    var agvs = db.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot).SplitTable(v => v.Take(2)).ToList();
+                    var stations = devs.Where(v => v.Entity.Code is "1001" or "1003" or "1005").ToList();
+                    //筛选出可用站台
+                    stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StationStatus.Auto))
+                                       .Where(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.PH_Status_1) && !v.Data3.Status.HasFlag(StationStatus.OT_Status))
+                                       .Where(v => !v.Data3.Status.HasFlag(StationStatus.Run))
+                                       .Where(v => agvs!.Select(a => a.Position).Contains(v.Entity.Code)).ToList(); // 筛选出可用站台
+                    if (!stations.Any())
+                    {
+                        World.Log($"无可用站台", LogLevelEnum.Mid);
+                        return;
+                    }
+
+                    //可用堆垛机
+                    var tunnelList = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel());//上一个地址是巷道的
+                    var tunnel = 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))) //筛选出堆垛机
+                                  .Select(v => new SRM(v, this.World)) //转换为SRM
+                                  .Where(v => !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic)//筛选出可用堆垛机
+                                  .Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel())
+                                  .Where(v => tunnelList.Select(s => s.Code).Contains(v.Code))
+                                  .MinBy(v => tunnelNo.IndexOf(v.Code));//按照巷道优先级排序    
+                    if (tunnel == null)
+                    {
+                        World.Log($"无可用巷道", LogLevelEnum.Mid);
+                        return;
+                    };
+                    //筛选出堆垛机的放货站台
+                    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 == tunnel.Code));                    
+                    agvTask.Status = AGVTaskStatus.Complete1;
+                    agvTask.Position = "1";
+                    agvTask.EditTime = DateTime.Now;
+                    db.Updateable(agvTask).ExecuteCommand();
+                    AgvApi.ContinueTask(agvTask.AgvID, nextPos.Entity.Code);
+
+                    taskInfo.Status = Entity.TaskStatus.AGVExecution;
+                    taskInfo.AddrNext = tunnel.Code;
+                    db.Updateable(taskInfo).ExecuteCommand();
+                    taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, "SRM", $"任务分配巷道[{tunnel.Code}],目标站台[{nextPos.Entity.Code}]");
+                    task = taskInfo;
+                    if (task == null) throw new Exception();
+                });
+            }
+            catch (Exception ex)
+            {
+                throw new KnownException(ex.Message, LogLevelEnum.High);
+            }
+        }
+        public override bool Select(Device dev)
+        {
+            return dev.HasFlag(DeviceFlags.检测门);
+        }
+    }
+}

+ 14 - 30
盘条库/WCS.WorkEngineering/Systems/一楼出库工位处理系统.cs

@@ -33,39 +33,23 @@ namespace WCS.WorkEngineering.Systems
                     throw new KnownException($"[{obj.Entity.Code}]--触发并发管控", LogLevelEnum.High);
                 }
                 RedisHub.Default.Set(key, obj.Entity.Code);
-                if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status) && !obj.Data3.Status.HasFlag(StationStatus.OT_Status))
-                {
-                    bool result = true; //是否需要申请出库任务,默认需要
+                //有任务需要执行
+                if (obj.Data3.Status.HasFlag(StationStatus.PH_Status) && obj.Data3.Status.HasFlag(StationStatus.PH_Status_1) && obj.Data3.Status.HasFlag(StationStatus.OT_Status))
+                {                   
                     SqlSugarHelper.Do(db =>
                     {
                         //当前站台是否有任务在执行
-                        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 (task.AgvTaskID == 0) throw new KnownException($"WCS任务[{task.ID}],等待AGV申请任务", LogLevelEnum.Mid);
-                            else
-                            {
-                                //检查对应的AGV任务状态是否大于退出储位状态
-                                var agv = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).First(v => v.ID == task.ID) ?? throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid);
-                                if (agv == null)
-                                {
-                                }
-                                else if (agv.AgvStatus >= AGVTaskStatus.Complete3)
-                                {
-                                    result = true;
-                                }
-                                else
-                                {
-                                    result = false;
-                                }
-                            }
-                        }
-                        else //无任务
-                        {
-                            result = true;
-                        }
-                    });
-                    if (result) WmsApi.ApplyStockOutTask(obj.Entity.Code);
+                        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 = AgvApi.叫料出库(agv.Station, Guid.NewGuid().ToString().Replace("-", ""), "1");
+                        agv.Status = AGVTaskStatus.Confirm;
+                        agv.AgvID = res.data;
+                        db.Default.Updateable(agv).SplitTable().ExecuteCommand();
+                        //更新WCS数据
+                        task.Status = Entity.TaskStatus.AGVExecution;
+                        db.Default.Updateable(task).ExecuteCommand();
+                        task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agv.AgvID}");
+                    });                 
                 }
             }
             finally

+ 67 - 0
盘条库/WCS.WorkEngineering/Systems/出入库站台处理系统.cs

@@ -0,0 +1,67 @@
+using ServiceCenter.Logs;
+using ServiceCenter.Redis;
+using ServiceCenter.SqlSugars;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WCS.Core;
+using WCS.Entity;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Protocol.BCR;
+using WCS.WorkEngineering.Protocol.SRM;
+using WCS.WorkEngineering.Protocol.Station;
+using WCS.WorkEngineering.WebApi.Controllers;
+using WCS.WorkEngineering.Worlds;
+using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
+
+namespace WCS.WorkEngineering.Systems
+{
+    /// <summary>
+    /// 出入库站台处理系统
+    /// </summary>
+    [BelongTo(typeof(MainWorld))]
+    [Description("出入库站台处理系统")]
+    public class 出入库站台处理系统 : DeviceSystem<Station>
+    {
+        protected override bool ParallelDo => true;
+
+        protected override bool SaveLogsToFile => true;
+
+        public override void Do(Station obj)
+        {
+            var key = $"WCS:Lock:{obj.Entity.Code}";
+            try
+            {
+                if (RedisHub.Default.Get(key) != null)
+                {
+                    throw new KnownException($"[{obj.Entity.Code}]--触发并发管控", LogLevelEnum.High);
+                }
+                RedisHub.Default.Set(key, obj.Entity.Code);
+                //无任务无光电申请分配货架
+                if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status) && !obj.Data3.Status.HasFlag(StationStatus.OT_Status) && obj.Data.TaskNumber == 0)
+                {                   
+                    SqlSugarHelper.Do(db =>
+                    {
+                        //当前站台是否已有任务在执行
+                        var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.AddrTo == obj.Entity.Code && v.Status < Entity.TaskStatus.Finish).OrderByDescending(v => v.AddTime).First();
+                        if (task == null)
+                        {
+                            WmsApi.ApplyStockOutTask(obj.Entity.Code);
+                        }
+                    });
+                }
+            }
+            finally
+            {
+                RedisHub.Default.Del(key);
+            }
+        }
+        public override bool Select(Device dev)
+        {
+            return dev.HasFlag(DeviceFlags.一楼出入库口);
+        }
+    }
+}

+ 185 - 0
盘条库/WCS.WorkEngineering/Systems/货架调度处理系统.cs

@@ -0,0 +1,185 @@
+using ServiceCenter.Logs;
+using ServiceCenter.SqlSugars;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WCS.Core;
+using WCS.Entity;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Protocol.BCR;
+using WCS.WorkEngineering.Protocol.SRM;
+using WCS.WorkEngineering.Protocol.Station;
+using WCS.WorkEngineering.WebApi.Controllers;
+using WCS.WorkEngineering.Worlds;
+using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
+
+namespace WCS.WorkEngineering.Systems
+{
+    /// <summary>
+    ///  货架调度处理系统
+    /// </summary>
+    [BelongTo(typeof(MainWorld))]
+    [Description("货架调度处理系统")]
+    public  class 货架调度处理系统 : DeviceSystem<Station>
+    {
+        protected override bool ParallelDo => true;
+        protected override bool SaveLogsToFile => true;
+            
+        private List<Station> devsIn = new List<Station>();
+        private List<Station> devsOut = new List<Station>();
+        private List<Station> devsCallOut = new List<Station>();
+        public 货架调度处理系统()
+        {                   
+            var devsIn = Device.All.Where(v => v.HasFlag(DeviceFlags.一楼入库口)).Select(v => new Station(v, this.World)).ToList();
+            var devsOut = Device.All.Where(v => v.HasFlag(DeviceFlags.一楼出库口)).Select(v => new Station(v, this.World)).ToList();
+            var devsCallOut = Device.All.Where(v => v.HasFlag(DeviceFlags.叫料站台)).Select(v => new Station(v, this.World)).ToList();
+        }
+
+        public override void Do(Station obj)
+        {           
+            //WCS_TaskInfo task = null;//处理完成的任务            
+            try
+            {
+                //入库口货架调度
+                if (obj.Entity.Code == "1001")
+                {
+                    if (devsIn.Count(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.PH_Status_1)) == 0)
+                        return;
+                    if (devsIn.Count(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.PH_Status_1)) == 2 &&
+                        devsOut.Count(v => v.Data3.Status.HasFlag(StationStatus.PH_Status)) == 6)
+                        return;
+                    SqlSugarHelper.Do(_db =>
+                    {
+                        var db = _db.Default;
+                        ShelfScheduling(1,db);
+                        #region 1
+                        //foreach (var item in devsIn)
+                        //{
+                        //    //入库口有空架子需搬走
+                        //    if (item.Data3.Status.HasFlag(StationStatus.PH_Status) && !item.Data3.Status.HasFlag(StationStatus.PH_Status_1) && !db.Queryable<WCS_AgvTaskInfo>().SplitTable().Any(v => v.Status < AGVTaskStatus.MissionCompleted && v.Position == item.Entity.Code))
+                        //    {
+                        //        if (item.Data.TaskNumber > 0)
+                        //        {
+                        //            task = db.Queryable<WCS_TaskInfo>().First(v => v.ID == item.Data.TaskNumber && v.Status < Entity.TaskStatus.Finish);
+                        //            if (task != null) throw new KnownException($"{item.Entity.Code}上有任务{item.Data.TaskNumber}未完成", LogLevelEnum.High);
+                        //        }
+                        //        //出库口不需要空架子,通知wms创建搬运任务
+                        //        if (devsOut.Count(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status)) == 0)
+                        //        {
+                        //            var res = WmsApi.PinKuCarryInTask(item.Entity.Code);
+                        //            continue;
+                        //        }
+                        //        else
+                        //        {
+                        //            //判断需要架子的出库口
+                        //            foreach (var i in devsOut)
+                        //            {
+                        //                //出库口没有货架且没有到此处的搬运任务
+                        //                if (!i.Data3.Status.HasFlag(StationStatus.PH_Status) && !db.Queryable<WCS_AgvTaskInfo>().SplitTable().Any(v => v.Status < AGVTaskStatus.MissionCompleted && v.Position == item.Entity.Code))
+                        //                {
+                        //                    //创建agv搬运任务
+                        //                    SqlSugarHelper.Do(db =>
+                        //                    {
+                        //                        var agvTask = new WCS_AgvTaskInfo()
+                        //                        {
+                        //                            ID = db.GetAGVTaskId(),
+                        //                            TaskType = AGVTaskType.ForkliftFilling,
+                        //                            Status = AGVTaskStatus.NewBuild,
+                        //                            Station = i.Entity.Code,
+                        //                            AddWho = "WCS",
+                        //                        };
+                        //                        db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                        //                    });
+                        //                }
+                        //            }
+                        //        }
+                        //    }
+                        //}
+                        #endregion
+                    });
+                }
+                else if (obj.Entity.Code == "1002")//叫料口货架调度
+                {
+                    //叫料
+                    if (!devsCallOut.Any(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.PH_Status_1)))
+                        return;
+                    if (devsCallOut.Count(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.PH_Status_1)) == 0)
+                        return;
+                    SqlSugarHelper.Do(_db =>
+                    {
+                        var db = _db.Default;
+                        ShelfScheduling(2, db);
+                    });                   
+                }                
+            }
+            catch (Exception ex)
+            {
+                throw new KnownException(ex.Message, LogLevelEnum.High);
+            }
+        }
+
+        private void ShelfScheduling(int type,SqlSugar.SqlSugarScopeProvider db)
+        {
+            List<Station> items = null;
+            items = type == 1 ? devsIn : devsCallOut;
+            
+            foreach (var item in items)
+            {               
+                //入库口有空架子需搬走
+                if (item.Data3.Status.HasFlag(StationStatus.PH_Status) && !item.Data3.Status.HasFlag(StationStatus.PH_Status_1) && !db.Queryable<WCS_AgvTaskInfo>().SplitTable().Any(v => v.Status < AGVTaskStatus.MissionCompleted && v.Position == item.Entity.Code))
+                {
+                    if (item.Data.TaskNumber > 0)
+                    {
+                        var task = db.Queryable<WCS_TaskInfo>().First(v => v.ID == item.Data.TaskNumber && v.Status < Entity.TaskStatus.Finish);
+                        if (task != null) throw new KnownException($"{item.Entity.Code}上有任务{item.Data.TaskNumber}未完成", LogLevelEnum.High);
+                    }
+                    //出库口不需要空架子,通知wms创建搬运任务
+                    if (devsOut.Count(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status)) == 0)
+                    {
+                        if (type == 1)
+                        {
+                            var res = WmsApi.PinKuCarryInTask(item.Entity.Code);
+                        }
+                        else if (type == 2) 
+                        {
+                            var res = WmsApi.PinKuCarryInTask(item.Entity.Code);
+                        }
+                        continue;
+                    }
+                    else
+                    {
+                        //判断需要架子的出库口
+                        foreach (var i in devsOut)
+                        {
+                            //出库口没有货架且没有到此处的搬运任务
+                            if (!i.Data3.Status.HasFlag(StationStatus.PH_Status) && !db.Queryable<WCS_AgvTaskInfo>().SplitTable().Any(v => v.Status < AGVTaskStatus.MissionCompleted && v.Position == item.Entity.Code))
+                            {
+                                //创建agv搬运任务
+                                SqlSugarHelper.Do(db =>
+                                {
+                                    var agvTask = new WCS_AgvTaskInfo()
+                                    {
+                                        ID = db.GetAGVTaskId(),
+                                        TaskType = AGVTaskType.ForkliftFilling,
+                                        Status = AGVTaskStatus.NewBuild,
+                                        Station = i.Entity.Code,
+                                        AddWho = "WCS",
+                                    };
+                                    db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
+                                });
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        public override bool Select(Device dev)
+        {
+            return dev.HasFlag(DeviceFlags.货架调度);  
+        }
+    }  
+}

+ 1 - 0
盘条库/WCS.WorkEngineering/WCS.WorkEngineering.csproj

@@ -16,6 +16,7 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <None Remove="Systems\AgvSystems.cs~RFf34461e.TMP" />
     <None Remove="Systems\puiaxxwa.5zv~" />
   </ItemGroup>
 

+ 2 - 2
盘条库/WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs

@@ -43,7 +43,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="taskCode">WMS任务号</param>
         /// <param name="priority">优先级</param>
         /// <returns></returns>
-        public static GenAgvSchedulingTaskResponse 满轮入库(string ctnrCode, string position, string taskCode, string priority)
+        public static GenAgvSchedulingTaskResponse 盘条入库(string ctnrCode, string position, string taskCode, string priority)
         {
             return GenAgvSchedulingTask("iwms_third", ctnrCode, "4", new List<positionCodeClass>()
             {
@@ -69,7 +69,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="taskCode">WMS任务号</param>
         /// <param name="priority">优先级</param>
         /// <returns></returns>
-        public static GenAgvSchedulingTaskResponse 机台补空(string position, string taskCode, string priority)
+        public static GenAgvSchedulingTaskResponse 叫料出库(string position, string taskCode, string priority)
         {
             return GenAgvSchedulingTask("iWMS", "", "4", new List<positionCodeClass>()
             {

+ 28 - 28
盘条库/WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -32,36 +32,36 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <param name="pos">目标位置</param>
         /// <returns></returns>
         [HttpPost]
-        public string AgvDebug(int type, string code, string pos)
-        {
-            try
-            {
-                switch (type)
-                {
-                    case 1:
-                        AgvApi.机台补空(pos, code, "1");
-                        break;
+        //public string AgvDebug(int type, string code, string pos)
+        //{
+        //    try
+        //    {
+        //        switch (type)
+        //        {
+        //            case 1:
+        //                AgvApi.机台补空(pos, code, "1");
+        //                break;
 
-                    case 2:
-                        //AgvApi.机台补满();
-                        break;
+        //            case 2:
+        //                //AgvApi.机台补满();
+        //                break;
 
-                    case 3:
-                        AgvApi.满轮入库(code, pos, Guid.NewGuid().ToString().Replace("-", ""), "1");
-                        break;
+        //            //case 3:
+        //            //    AgvApi.满轮入库(code, pos, Guid.NewGuid().ToString().Replace("-", ""), "1");
+        //            //    break;
 
-                    default:
-                        break;
-                }
-                return "成功";
-            }
-            catch (Exception ex)
-            {
-                return $"Error-----" +
-                      $"{ex.Message}------" +
-                      $"{ex.StackTrace}";
-            }
-        }
+        //            default:
+        //                break;
+        //        }
+        //        return "成功";
+        //    }
+        //    catch (Exception ex)
+        //    {
+        //        return $"Error-----" +
+        //              $"{ex.Message}------" +
+        //              $"{ex.StackTrace}";
+        //    }
+        //}
 
         /// <summary>
         ///  背负式AGV请求出库任务
@@ -214,7 +214,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                     //case "end": //表示请求巷道
                                     //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
                                     //    break;
-
+                                    //入库任务、叫料任务、搬运任务
                                     case "applyContinue": //表示请求巷道
                                         agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
                                         break;

+ 1 - 13
盘条库/WCS.WorkEngineering/WebApi/Controllers/WcsController.cs

@@ -110,19 +110,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
                                 case TaskType.Delivery:
 
                                     break;
-
-                                case TaskType.EmptyInit:
-                                    if (task.Status != Entity.TaskStatus.WaitingToExecute)
-                                    {
-                                        response.ResDataList.Add(new HandleTaskResponse()
-                                        {
-                                            IsSuccess = false,
-                                            TaskNo = item,
-                                            Message = $"只能取消待执行状态空轮初始化任务",
-                                        });
-                                        continue;
-                                    }
-                                    break;
+                                
                             }
 
                             SRes cancelRes = WmsApi.CarryTaskInfo(response, item, 106);

+ 22 - 1
盘条库/WCS.WorkEngineering/WebApi/Controllers/WmsApi.cs

@@ -3,6 +3,7 @@ using ServiceCenter.Extensions;
 using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using ServiceCenter.WebApi;
+using System.DirectoryServices.Protocols;
 using WCS.WorkEngineering.WebApi.Models.AGV.Response;
 using WCS.WorkEngineering.WebApi.Models.WCS.Request;
 using WCS.WorkEngineering.WebApi.Models.WCS.Response;
@@ -88,7 +89,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         /// <exception cref="Exception"></exception>
         public static SRes<string> GetTunnelPriorityList(int wcsTaskNum)
         {
-            var res = APICaller.CallApi2<SRes<string>>(WMSUrl + "/api/Hj/GetTunnelPriorityList", new GetTunnelPriorityListRequest
+            var res = APICaller.CallApi2<SRes<string>>(WMSUrl + "/api/Pt/GetTunnelPriorityList", new GetTunnelPriorityListRequest
             {
                 TaskNum = wcsTaskNum,
             });
@@ -185,6 +186,26 @@ namespace WCS.WorkEngineering.WebApi.Controllers
             return res;
         }
 
+        /// <summary>
+        /// 申请入库货架搬运任务
+        /// </summary>
+        /// <param name="equ">起点位置</param>
+        /// <returns></returns>
+        /// <exception cref="KnownException"></exception>
+        public static SRes PinKuCarryInTask(string equ)
+        {
+            var request = new PinKuCarryInTaskRequest
+            {
+                Equip = equ
+            };
+            var res = APICaller.CallApi2<SRes>(WMSUrl + "/api/Pt/PinKuCarryInTask", request);
+            if (res.ResCode != ResponseStatusCodeEnum.Sucess)
+            {
+                throw new KnownException(res.ResMsg, LogLevelEnum.High);
+            }
+            return res;
+        }
+
         /// <summary>
         ///  获取各巷道剩余空轮数量
         /// </summary>

+ 21 - 0
盘条库/WCS.WorkEngineering/WebApi/Models/WMS/Request/PinKuCarryInTaskRequest.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WCS.WorkEngineering.WebApi.Models.WMS.Request
+{
+    /// <summary>
+    /// 请求入库货架搬运任务实体
+    /// </summary>
+    public class PinKuCarryInTaskRequest
+    {
+        /// <summary>
+        /// 起点设备号
+        /// </summary>
+        [Required(ErrorMessage = "{0} 不可为空")]
+        public string Equip { get; set; }
+    }
+}

+ 52 - 14
盘条库/WCS.WorkEngineering/WorkStart.cs

@@ -98,11 +98,7 @@ namespace WCS.WorkEngineering
 
             foreach (var item in RgvInfo)
             {
-                var conv = new Device($"RGV{item.Code}");
-                conv.AddFlag(DeviceFlags.RGV);
-                conv.AddProtocol<IRGV520>(0, 520, item.IP);
-                conv.AddProtocol<IRGV521>(0, 521, item.IP);
-                //conv.AddProtocol<IStation523>(, 523, item.IP);
+                
             }
 
             #endregion 初始化RGV相关信息
@@ -115,13 +111,13 @@ namespace WCS.WorkEngineering
 
             foreach (var item in TrussInfo)
             {
-                var conv = new Device($"Truss{item.Code}");
-                conv.AddFlag(DeviceFlags.桁架);
-                conv.AddProtocol<ITruss520>(0, 520, item.IP);
-                conv.AddProtocol<ITruss521>(0, 521, item.IP);
-                conv.AddProtocol<ITruss523>(0, 523, item.IP);
-                conv.AddProtocol<ITruss530>(0, 530, item.IP);
-                conv.AddProtocol<ITruss531>(0, 531, item.IP);
+                //var conv = new Device($"Truss{item.Code}");
+                //conv.AddFlag(DeviceFlags.桁架);
+                //conv.AddProtocol<ITruss520>(0, 520, item.IP);
+                //conv.AddProtocol<ITruss521>(0, 521, item.IP);
+                //conv.AddProtocol<ITruss523>(0, 523, item.IP);
+                //conv.AddProtocol<ITruss530>(0, 530, item.IP);
+                //conv.AddProtocol<ITruss531>(0, 531, item.IP);
             }
 
             #endregion 初始化桁架相关信息
@@ -130,7 +126,7 @@ namespace WCS.WorkEngineering
 
             int ip = 41;
 
-            for (int i = 0; i <= 1; i++)
+            for (int i = 0; i <= 7; i++)
             {
                 var srm = new Device($"SRM{i + 1}");
                 srm.AddFlag(DeviceFlags.堆垛机);
@@ -151,6 +147,36 @@ namespace WCS.WorkEngineering
 
             List<RouteInfo> routeInfos = new List<RouteInfo>
             {
+                new RouteInfo("SRM1", new string[] { "TY1","TY2"}),
+                new RouteInfo("SRM2", new string[] { "TY3","TY4"}),
+                new RouteInfo("SRM3", new string[] { "TY5","TY6" }),
+                new RouteInfo("SRM4", new string[] { "TY7","TY8" }),
+                new RouteInfo("TY1", new string[] { "SRM1" }),
+                new RouteInfo("TY2", new string[] { "SRM1" }),
+                new RouteInfo("TY3", new string[] { "SRM2" }),
+                new RouteInfo("TY4", new string[] { "SRM2" }),
+                new RouteInfo("TY5", new string[] { "SRM3" }),
+                new RouteInfo("TY6", new string[] { "SRM3" }),
+                new RouteInfo("TY7", new string[] { "SRM4" }),
+                new RouteInfo("TY8", 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("TY4", new string[] { "1001" }),
+                new RouteInfo("TY5", new string[] { "1011", "1021" }),
+                new RouteInfo("TY6", new string[] { "1013", "1023" }),
+                new RouteInfo("TY7", new string[] { "1015", "1025" }),
+                new RouteInfo("TY8", new string[] { "1003" }),
+                //出
+                new RouteInfo("1012", new string[] { "TY1" }),
+                new RouteInfo("1022", new string[] { "TY2" }),
+                new RouteInfo("1014", new string[] { "TY3" }),
+                new RouteInfo("1024", new string[] { "TY4" }),
+                new RouteInfo("1016", new string[] { "TY5" }),
+                new RouteInfo("1026", new string[] { "TY6" }),
+                new RouteInfo("1016", new string[] { "TY7" }),
+                new RouteInfo("1026", new string[] { "TY8" })
             };
 
             foreach (var item in routeInfos)
@@ -171,7 +197,19 @@ 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>() { "1001", "1002" } },
+                { DeviceFlags.叫料站台, new List<string>() { "1", "2","3","4","5","6" } },
+
+        };
 
             devices.ForEach(item =>
             {