林豪 左 3 years ago
parent
commit
fce30bae8a

+ 17 - 2
Projects/永冠OPP/WCS.Entity.Protocol/WCS_TASK.cs

@@ -48,17 +48,31 @@ namespace WCS.Entity
         [StringLength(10)]
         public string TUNNEL { get; set; }
 
+        /// <summary>
+        /// 倒库目标巷道
+        /// dump library
+        /// </summary>
+        [StringLength(10)]
+        public string TUNNELDL { get; set; }
+
         /// <summary>
         ///
         /// </summary>
         public int FLOOR { get; set; }
 
         /// <summary>
-        /// 设备
+        /// 设备/执行设备,即堆垛机
         /// </summary>
         [StringLength(20)]
         public string DEVICE { get; set; }
 
+        /// <summary>
+        /// 倒库目标设备/执行设备,即堆垛机
+        /// dump library
+        /// </summary>
+        [StringLength(20)]
+        public string DEVICEDL { get; set; }
+
         /// <summary>
         /// 堆垛机放货站台
         /// </summary>
@@ -153,6 +167,7 @@ namespace WCS.Entity
         出库 = 2,
         移库 = 3,
         输送 = 5,
+        倒库 = 6
     }
 
     public enum TaskStatus
@@ -166,4 +181,4 @@ namespace WCS.Entity
         已完成 = 99,
         已取消 = 106
     }
-}
+}

+ 1 - 0
Projects/永冠OPP/WCS.Service/Extensions/TaskExtension.cs

@@ -60,6 +60,7 @@ namespace WCS.Service.Extensions
         /// <param name="srmFork">货叉</param>
         public static void GetSrmStationAndaddNext(this WCS_TASK task, SrmFork srmFork)
         {
+            //TODO:确定在倒库任务重是否能生效
             //取任务巷道到达目标地址的下一个地址,即任务堆垛机的站台对应的设备组
             var stations = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER == Device.Find(task.TUNNEL).GetPath(task.ADDRTO.Replace("G", ""))))
                                  .Select(v => v.Create<StationDeviceGroup>())

+ 88 - 59
Projects/永冠OPP/WCS.Service/WebApi/WCSApi.cs

@@ -24,71 +24,15 @@ namespace WCS.Service.WebApi
                 {
                     foreach (var obj in list)
                     {
-                        if (obj.TaskType == "3")//移库任务
+                        if (obj.TaskType == "1") //入库任务
                         {
                             var wmstaskid = int.Parse(obj.WMSTaskNo);
                             if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmstaskid))
                                 throw new Exception("任务号" + wmstaskid + "重复下发");
 
-                            var scid = int.Parse(obj.SRMNo.Last().ToString());
-                            var tunnel = "TY" + obj.StartTunnel;
-                            var task = new WCS_TASK
-                            {
-                                TYPE = TaskType.移库,
-                                STATUS = WCS.Entity.TaskStatus.新建,
-                                DEVICE = "SRM" + obj.SRMNo.Last(),
-                                BARCODE = obj.PalletCode,
-                                ADDRFROM = obj.StartLocation,
-                                ADDRTO = obj.EndLocation,
-                                UPDATETIME = DateTime.Now,
-                                UPDATEUSER = "WMS",
-                                TUNNEL = tunnel,
-                                WMSTASK = int.Parse(obj.WMSTaskNo),
-                                TaskGroupKey = obj.TaskGroupKey
-                            };
-                            db.Default.Add(task);
-                        }
-                        else if (obj.TaskType == "2")
-                        {  //出库任务
-                            var wmsTaskId = int.Parse(obj.WMSTaskNo);
-                            if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmsTaskId))
-                                throw new Exception("任务号" + wmsTaskId + "重复下发");
-
-                            var tunnel = "TY" + obj.SRMNo.Last();
-
-                            var task = new WCS_TASK
-                            {
-                                TYPE = TaskType.出库,
-                                STATUS = TaskStatus.新建,
-                                DEVICE = "SRM" + obj.SRMNo.Last(),
-                                BARCODE = obj.PalletCode,
-                                ADDRFROM = $"{obj.StartRow}-{obj.StartCol}-{obj.StartLayer}",
-                                ADDRTO = obj.EndLocation,
-                                UPDATETIME = DateTime.Now,
-                                UPDATEUSER = "WMS",
-                                TUNNEL = tunnel,
-                                WMSTASK = int.Parse(obj.WMSTaskNo),
-                                ADDRNEXT = obj.EndLocation,
-                                Length = obj.Length,
-                                MaterialCode = obj.MaterialCode,
-                                FLOOR = obj.EndLocation == "G1340" ? 1 : 2
-                            };
-
-                            task.TaskGetSrmStation();
-                            //task.GetSrmStationAndaddNext(SrmFork.货叉1);
-                            //task.SRMSTATION = Device.Where(v => v.IsDevGroup()).FirstOrDefault(v => v.DEVICEGROUP.Any(b => b.MEMBER.CODE == task.SRMSTATION))?.CODE;
-                            //task.ADDRNEXT = string.Empty;
-
-                            db.Default.Add(task);
-                        }
-                        else if (obj.TaskType == "1")
-                        {//入库任务
-                            var wmstaskid = int.Parse(obj.WMSTaskNo);
-                            if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmstaskid))
-                                throw new Exception("任务号" + wmstaskid + "重复下发");
-
                             if (obj.StartLocation.Contains("_Back_"))
-                            {//生成AGV入库任务
+                            {
+                                //生成AGV入库任务
                                 var ws = int.Parse(obj.StartLocation.Split('_')[1]);
                                 var agvtask = new WCS_AGVTask
                                 {
@@ -133,6 +77,91 @@ namespace WCS.Service.WebApi
                                 db.Default.Add(task);
                             }
                         }
+                        else if (obj.TaskType == "2")//出库任务
+                        {
+                            var wmsTaskId = int.Parse(obj.WMSTaskNo);
+                            if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmsTaskId))
+                                throw new Exception("任务号" + wmsTaskId + "重复下发");
+
+                            var tunnel = "TY" + obj.SRMNo.Last();
+
+                            var task = new WCS_TASK
+                            {
+                                TYPE = TaskType.出库,
+                                STATUS = TaskStatus.新建,
+                                DEVICE = "SRM" + obj.SRMNo.Last(),
+                                BARCODE = obj.PalletCode,
+                                ADDRFROM = $"{obj.StartRow}-{obj.StartCol}-{obj.StartLayer}",
+                                ADDRTO = obj.EndLocation,
+                                UPDATETIME = DateTime.Now,
+                                UPDATEUSER = "WMS",
+                                TUNNEL = tunnel,
+                                WMSTASK = int.Parse(obj.WMSTaskNo),
+                                ADDRNEXT = obj.EndLocation,
+                                Length = obj.Length,
+                                MaterialCode = obj.MaterialCode,
+                                FLOOR = obj.EndLocation == "G1340" ? 1 : 2
+                            };
+
+                            task.TaskGetSrmStation();
+                            db.Default.Add(task);
+                        }
+                        else if (obj.TaskType == "3") //移库任务
+                        {
+                            var wmstaskid = int.Parse(obj.WMSTaskNo);
+                            if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmstaskid))
+                                throw new Exception("任务号" + wmstaskid + "重复下发");
+
+                            var scid = int.Parse(obj.SRMNo.Last().ToString());
+                            var tunnel = "TY" + obj.StartTunnel;
+                            var task = new WCS_TASK
+                            {
+                                TYPE = TaskType.移库,
+                                STATUS = WCS.Entity.TaskStatus.新建,
+                                DEVICE = "SRM" + obj.SRMNo.Last(),
+                                BARCODE = obj.PalletCode,
+                                ADDRFROM = obj.StartLocation,
+                                ADDRTO = obj.EndLocation,
+                                UPDATETIME = DateTime.Now,
+                                UPDATEUSER = "WMS",
+                                TUNNEL = tunnel,
+                                WMSTASK = int.Parse(obj.WMSTaskNo),
+                                TaskGroupKey = obj.TaskGroupKey
+                            };
+                            db.Default.Add(task);
+                        }
+                        else if (obj.TaskType == "6") //倒库任务
+                        {
+                            var wmsTaskId = int.Parse(obj.WMSTaskNo);
+                            if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmsTaskId))
+                                throw new Exception("任务号" + wmsTaskId + "重复下发");
+
+                            var srmNo = obj.SRMNo.Last();
+                            var endSrmNo = obj.EndSRMNo.Last();
+
+                            var task = new WCS_TASK
+                            {
+                                TYPE = TaskType.出库,
+                                STATUS = TaskStatus.新建,
+                                BARCODE = obj.PalletCode,
+                                ADDRFROM = $"{obj.StartRow}-{obj.StartCol}-{obj.StartLayer}",
+                                ADDRTO = $"{obj.EndRow}-{obj.EndCol}-{obj.EndLayer}",
+                                UPDATETIME = DateTime.Now,
+                                UPDATEUSER = "WMS",
+                                TUNNEL = $"TY{srmNo}",
+                                DEVICE = $"SRM{srmNo}",
+                                TUNNELDL = $"TY{endSrmNo}",
+                                DEVICEDL = $"SRM{endSrmNo}",
+                                WMSTASK = int.Parse(obj.WMSTaskNo),
+                                ADDRNEXT = obj.EndLocation,
+                                Length = obj.Length,
+                                MaterialCode = obj.MaterialCode,
+                                FLOOR = obj.EndLocation == "G1340" ? 1 : 2
+                            };
+
+                            task.TaskGetSrmStation();
+                            db.Default.Add(task);
+                        }
                     }
                     db.Default.SaveChanges();
                 });

+ 105 - 21
Projects/永冠OPP/WCS.Service/WebApi/WMS/PushCreateWcsTaskRequest.cs

@@ -2,26 +2,110 @@
 {
     public class PushCreateWcsTaskRequest
     {
-        public string WMSTaskNo { get; set; }//WMS任务号
-        public string TaskGroupKey { get; set; } //任务组ID
-        public string StartLocation { get; set; }//起点地址
-        public string EndLocation { get; set; }//目标地址
-        public string Warehouse { get; set; }//仓库名称
-        public string PalletCode { get; set; }//托盘条码
-        public string TaskState { get; set; }//任务状态
-        public string StartRow { get; set; }//起点行
-        public string StartCol { get; set; }//起点列
-        public string StartLayer { get; set; }//起点层
-        public string EndRow { get; set; }//目标行
-        public string EndCol { get; set; }//目标列
-        public string EndLayer { get; set; }//目标层
-        public string StartTunnel { get; set; }//起点巷道
-        public string EndTunnel { get; set; }//终点巷道
-        public string WMSSendName { get; set; }//WMS下发人名称
-        public string TaskType { get; set; }//任务类型
-        public string Priority { get; set; }//优先级
-        public string SRMNo { get; set; }//堆垛机编号
-        public bool IsIceBox { get; set; } = false;//是否冰箱
+        /// <summary>
+        /// WMS任务号
+        /// </summary>
+        public string WMSTaskNo { get; set; }
+
+        /// <summary>
+        /// 任务组ID
+        /// </summary>
+        public string TaskGroupKey { get; set; }
+
+        /// <summary>
+        /// 起点地址
+        /// </summary>
+        public string StartLocation { get; set; }
+
+        /// <summary>
+        /// 目标地址
+        /// </summary>
+        public string EndLocation { get; set; }
+
+        /// <summary>
+        /// 仓库名称
+        /// </summary>
+        public string Warehouse { get; set; }
+
+        /// <summary>
+        /// 托盘条码
+        /// </summary>
+        public string PalletCode { get; set; }
+
+        /// <summary>
+        /// 任务状态
+        /// </summary>
+        public string TaskState { get; set; }
+
+        /// <summary>
+        /// 起点行
+        /// </summary>
+        public string StartRow { get; set; }
+
+        /// <summary>
+        /// 起点列
+        /// </summary>
+        public string StartCol { get; set; }
+
+        /// <summary>
+        /// 起点层
+        /// </summary>
+        public string StartLayer { get; set; }
+
+        /// <summary>
+        /// 目标行
+        /// </summary>
+        public string EndRow { get; set; }
+
+        /// <summary>
+        /// 目标列
+        /// </summary>
+        public string EndCol { get; set; }
+
+        /// <summary>
+        /// 目标层
+        /// </summary>
+        public string EndLayer { get; set; }
+
+        /// <summary>
+        /// 起点巷道
+        /// </summary>
+        public string StartTunnel { get; set; }
+
+        /// <summary>
+        /// 终点巷道
+        /// </summary>
+        public string EndTunnel { get; set; }
+
+        /// <summary>
+        /// WMS下发人名称
+        /// </summary>
+        public string WMSSendName { get; set; }
+
+        /// <summary>
+        /// 任务类型
+        /// </summary>
+        public string TaskType { get; set; }
+
+        /// <summary>
+        /// 优先级
+        /// </summary>
+        public string Priority { get; set; }
+
+        /// <summary>
+        /// 堆垛机编号
+        /// </summary>
+        public string SRMNo { get; set; }
+
+        /// <summary>
+        /// 终点堆垛机编号
+        /// </summary>
+        public string EndSRMNo { get; set; }
+
+        /// <summary>
+        /// 是否冰箱
+        /// </summary>
+        public bool IsIceBox { get; set; } = false;
 
         /// <summary>
         /// 分组编号
@@ -80,4 +164,4 @@
         /// </summary>
         public int Type { get; set; }
     }
-}
+}

+ 2 - 2
Projects/永冠OPP/WCS.Service/WebApi/WMS/Response/I_WCS_GetInTaskResponse.cs

@@ -30,7 +30,7 @@ namespace WCS.Service.Entity
         public string TaskGroupKey { get; set; } = "0";
 
         /// <summary>
-        /// 任务类型(1:入库2:出库3:移库4:移动(搬运) 5:异常)
+        /// 任务类型(1:入库2:出库3:移库4:移动(搬运) 5:异常 )
         /// </summary>
         public int TaskType { get; set; }
 
@@ -65,4 +65,4 @@ namespace WCS.Service.Entity
         public string Memo2 { get; set; } = "";
         public string Memo3 { get; set; } = "";
     }
-}
+}

+ 3 - 3
Projects/永冠OPP/WCS.Service/WebApi/WMS/WMS.cs

@@ -258,7 +258,7 @@ namespace WCS.Service
                     InfoLog.INFO_I_WCS_GetExcTask(device + ":" + exMsg);
                     if (!res.ResType) throw new WarnException(res.ResMessage);
                 }
-                catch (Exception ex)
+                catch (Exception)
                 {
                 }
             });
@@ -283,7 +283,7 @@ namespace WCS.Service
                 if (!res.ResType)
                     throw new WarnException(res.ResMessage);
             }
-            catch (Exception ex)
+            catch (Exception)
             {
                 Console.WriteLine("I_WCS_PutDevInfo" + "接口调用失败");
             }
@@ -305,4 +305,4 @@ namespace WCS.Service
             catch { }
         }
     }
-}
+}

+ 272 - 25
Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs

@@ -22,12 +22,12 @@ namespace WCS.Service.Works.SRM
         {
             obj.EX(srmDevice =>
             {
-                var deviceCode = srmDevice.Entity.CODE;
+                var deviceCode = obj.Entity.CODE;
                 //先检查堆垛机是否报警
                 if (srmDevice.Data3.SCAlarm != 0)
                 {
-                    if (srmDevice.Entity.WakeupOn(5000)) WMS.DevInfo(srmDevice.Entity.CODE, srmDevice.Data3.SCAlarm.ToString());
-                    InfoLog.INFO_SRMALARM($"{srmDevice.Entity.CODE}-{srmDevice.Data3.SCAlarm}");
+                    if (srmDevice.Entity.WakeupOn(5000)) WMS.DevInfo(deviceCode, srmDevice.Data3.SCAlarm.ToString());
+                    InfoLog.INFO_SRMALARM($"{deviceCode}-{srmDevice.Data3.SCAlarm}");
                     return;
                 }
                 if (srmDevice.Data.FinishedACK_1 == 1 || srmDevice.Data.FinishedACK_2 == 1) throw new WarnException($"堆垛机完成任务WCS反馈信号未清除");
@@ -59,9 +59,9 @@ namespace WCS.Service.Works.SRM
                 //处理堆垛机已完成的任务
                 if (srmDevice.Data2.FinishedTask_1 != 0 || srmDevice.Data2.FinishedTask_2 != 0)
                 {
-                    InfoLog.INFO_SRMINFO($"开始完成任务:[{srmDevice.Entity.CODE}]-{srmDevice.Data2.FinishedTask_1}-{srmDevice.Data2.FinishedTask_2}");
+                    InfoLog.INFO_SRMINFO($"开始完成任务:[{deviceCode}]-{srmDevice.Data2.FinishedTask_1}-{srmDevice.Data2.FinishedTask_2}");
                     srmDevice.FinishedTaskHandle();
-                    InfoLog.INFO_SRMINFO($"完成任务处理结束:[{srmDevice.Entity.CODE}]-{srmDevice.Data2.FinishedTask_1}-{srmDevice.Data2.FinishedTask_2}");
+                    InfoLog.INFO_SRMINFO($"完成任务处理结束:[{deviceCode}]-{srmDevice.Data2.FinishedTask_1}-{srmDevice.Data2.FinishedTask_2}");
                     return;
                 }
 
@@ -70,25 +70,272 @@ namespace WCS.Service.Works.SRM
 
                 var isTransfer = new List<WCS_TASK>(); //是否有移库任务
                 WCS_TASK enterPriority = new(), outPriority = new(); //出入库优先级任务
+                var dumpLibrary = new List<WCS_TASK>();
                 //再检查是否有等待执行的货物
                 DB.Do(db =>
                 {
-                    var task = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == srmDevice.Entity.CODE).FirstOrDefault(v => v.STATUS == TaskStatus.堆垛机执行);
+                    var task = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode).FirstOrDefault(v => v.STATUS == TaskStatus.堆垛机执行);
                     if (task != null) throw new WarnException($"[{deviceCode}]有正在执行的任务:[{task.ID}]");
-                    //属于当前堆垛机未执行的移库任务
-                    isTransfer = db.Default.Set<WCS_TASK>().AsNoTracking().Where(v => v.DEVICE == srmDevice.Entity.CODE && v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行).ToList();
-                    //判断是否存在调整优先级任务,存在初始化isTransfer值 让本次执行优先任务
-                    if (db.Default.Set<WCS_TASK>().AsNoTracking().Any(v => v.DEVICE == srmDevice.Entity.CODE && v.TYPE != TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行 && v.Priority > 0))
-                        isTransfer = new List<WCS_TASK>();
-                    enterPriority = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == srmDevice.Entity.CODE && v.TYPE == TaskType.入库 && v.STATUS < TaskStatus.堆垛机执行)
-                                                                 .OrderByDescending(v => v.Priority).FirstOrDefault();
-                    outPriority = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == srmDevice.Entity.CODE && v.TYPE == TaskType.出库 && v.STATUS < TaskStatus.堆垛机执行)
-                                                                  .OrderByDescending(v => v.Priority).FirstOrDefault();
+                    //检测是否有未结束的倒库任务
+                    dumpLibrary = db.Default.Set<WCS_TASK>().Where(v => (v.DEVICE == deviceCode || v.DEVICEDL == deviceCode) && v.TYPE == TaskType.倒库 && v.STATUS < TaskStatus.已完成).ToList();
+                    if (!dumpLibrary.Any())
+                    {
+                        //属于当前堆垛机未执行的移库任务
+                        isTransfer = db.Default.Set<WCS_TASK>().AsNoTracking().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行).ToList();
+                        //判断是否存在调整优先级任务,存在初始化isTransfer值 让本次执行优先任务
+                        if (db.Default.Set<WCS_TASK>().AsNoTracking().Any(v => v.DEVICE == deviceCode && v.TYPE != TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行 && v.Priority > 0))
+                            isTransfer = new List<WCS_TASK>();
+                        enterPriority = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.入库 && v.STATUS < TaskStatus.堆垛机执行)
+                                                                     .OrderByDescending(v => v.Priority).FirstOrDefault();
+                        outPriority = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.出库 && v.STATUS < TaskStatus.堆垛机执行)
+                                                                      .OrderByDescending(v => v.Priority).FirstOrDefault();
+                    }
                 });
 
                 //最后一个是否是出库任务
                 var lastIsOut = srmDevice.Entity.Get<bool>("LastIsOut");
                 srmDevice.Entity.Set("LastIsOut", !lastIsOut);
+                if (dumpLibrary.Any())
+                {
+                    //检查当前堆垛机是起始点还是目标点
+                    var lastOut = srmDevice.Entity.Get<bool>("LastOut");
+                    srmDevice.Entity.Set("LastOut", !lastIsOut);
+                    if (lastOut) //入库
+                    {
+                        var arrIn = srmDevice.GetPickPoint()
+                                   .Where(v => Device.Where(d => d.IsConv()).Select(d => d.Device<IStation521>()).Any(d => d.Data.Goodsend == v.Entity.Code())) //有正在前往取货点的任务
+                                   .ToList();
+
+                        if (!arrIn.Any()) return; //当前堆垛机无入库任务
+
+                        //入库口设备信息 找一个有任务有光电且不在运行状态位的取货点 如果找不到代表任务还在输送途中
+                        var station = arrIn.OrderBy(v => v.Data2.Tasknum > 0 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位) ? 0 : 1)
+                                           .ThenBy(v => v.UpdateTime)
+                                           .FirstOrDefault() ?? throw new WarnException($"[{deviceCode}]等待入库任务输送到位");
+
+                        //根据上述筛选条件筛选出来的入库任务 找到对应的设备组
+                        var item = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER.CODE == station.Entity.CODE)).Single();
+                        //对数据进行排序,根据CAD图纸规划,取货点两个设备中设备号较大的一个一定对应到堆垛机的一工位货叉
+                        //因此按照降序进行排序,可以保证数组中第一个一定是放到堆垛机一工位的数据
+                        var devise = item.DEVICEGROUP.Select(v => v.MEMBER)
+                                                   .Select(v => v.Create<StationDevice>())
+                                                   .OrderByDescending(v => v.Entity.CODE)
+                                                   .ToArray();
+                        var finishTaskList = new List<FinishTaskList<int>>(); //成功分配货位的任务
+                                                                              //取巷道
+                        DB.Do(db =>
+                        {
+                            //检测有效任务数与实际任务是是否相等
+                            var validDev = devise.Where(v => v.Data2.Tasknum > 10000 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位));
+                            var stationDevices = validDev as StationDevice[] ?? validDev.ToArray();
+                            if (!stationDevices.Any()) throw new DoException("无有效入库任务");
+                            var tasking = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == stationDevices.First().Data2.Tasknum);
+                            var taskList = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == tasking.TaskGroupKey && v.TYPE == TaskType.倒库);
+                            if (stationDevices.Count() != taskList) throw new WarnException($"任务数量不匹配,设备-{stationDevices.Count()},WCS-{taskList}");
+
+                            foreach (var dev in stationDevices)
+                            {
+                                var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == dev.Data2.Tasknum) ?? throw new WarnException($"设备有光电有任务且不在运行状态,但WCS找不到任务{dev.Data2.Tasknum}");
+                                var oldTask = task.STATUS;
+                                var tunnel = dev.Entity.ROUTES.First().NEXT.CODE;
+                                I_WCS_GetWareCellResponse loc;
+                                //判定当前设备对应的堆垛机工位
+                                if (dev.Entity.CODE == devise[0].Entity.CODE) loc = WMS.GetLocalIn(task.WMSTASK, tunnel, dev.Entity.CODE, Entity.WareCellForkNum.货叉1); //一工位
+                                else if (dev.Entity.CODE == devise[1].Entity.CODE) loc = WMS.GetLocalIn(task.WMSTASK, tunnel, dev.Entity.CODE, Entity.WareCellForkNum.货叉2); //2工位
+                                else throw new WarnException($"设备{dev.Entity.CODE}无法对应至堆垛机的任一一个工位");
+
+                                task.UPDATETIME = DateTime.Now;
+                                task.STATUS = TaskStatus.堆垛机执行;
+                                task.ADDRTO = $"{loc.Row}-{loc.Colomn}-{loc.Layer}";
+                                task.DEVICE = deviceCode;
+                                task.TUNNEL = tunnel;
+                                task.CreateStatusLog(db, $"状态由{oldTask}变更至{task.STATUS}", this.GetType());
+                                finishTaskList.Add(new FinishTaskList<int>(task.ID, dev));
+                            }
+                            db.Default.SaveChanges();
+                        });
+                        DB.Do(db =>
+                        {
+                            foreach (var finish in finishTaskList)
+                            {
+                                var task = db.Default.Set<WCS_TASK>().Find(finish.FinishCode);
+                                var addTo = task!.ADDRTO.Split("-");
+                                if (finish.Station.Entity.CODE == devise[0].Entity.CODE)  //一工位
+                                {
+                                    InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]1工位-开始:[{srmDevice.Data.TaskID_1}][{srmDevice.Data.SLine_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.ECol_1}][{srmDevice.Data.ELayer_1}][{srmDevice.Data.VoucherNo_1}]--[{finishTaskList.Count.ToShort()}]");
+                                    srmDevice.Data.TaskID_1 = task.ID;
+                                    srmDevice.Data.SLine_1 = finish.Station.Entity.CODE.ToShort();
+                                    srmDevice.Data.SCol_1 = 0;
+                                    srmDevice.Data.SLayer_1 = 0;
+                                    srmDevice.Data.ELine_1 = addTo[0].ToShort();
+                                    srmDevice.Data.ECol_1 = addTo[1].ToShort();
+                                    srmDevice.Data.ELayer_1 = addTo[2].ToShort();
+                                    srmDevice.Data.RES1_1 = finishTaskList.Count.ToShort();
+                                    srmDevice.Data.VoucherNo_1++;
+                                    InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]1工位-结束:[{srmDevice.Data.TaskID_1}][{srmDevice.Data.SLine_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.ECol_1}][{srmDevice.Data.ELayer_1}][{srmDevice.Data.VoucherNo_1}]--[{finishTaskList.Count.ToShort()}]");
+                                }
+                                else if (finish.Station.Entity.CODE == devise[1].Entity.CODE)
+                                {
+                                    InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]2工位-开始:[{srmDevice.Data.TaskID_2}][{srmDevice.Data.SLine_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.ECol_2}][{srmDevice.Data.ELayer_2}][{srmDevice.Data.VoucherNo_2}]--[{finishTaskList.Count.ToShort()}]");
+                                    srmDevice.Data.TaskID_2 = task.ID;
+                                    srmDevice.Data.SLine_2 = finish.Station.Entity.CODE.ToShort();
+                                    srmDevice.Data.SCol_2 = 0;
+                                    srmDevice.Data.SLayer_2 = 0;
+                                    srmDevice.Data.ELine_2 = addTo[0].ToShort();
+                                    srmDevice.Data.ECol_2 = addTo[1].ToShort();
+                                    srmDevice.Data.ELayer_2 = addTo[2].ToShort();
+                                    srmDevice.Data.RES1_2 = finishTaskList.Count.ToShort();
+                                    srmDevice.Data.VoucherNo_2++;
+                                    InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]2工位-结束:[{srmDevice.Data.TaskID_2}][{srmDevice.Data.SLine_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.ECol_2}][{srmDevice.Data.ELayer_2}][{srmDevice.Data.VoucherNo_2}]--[{finishTaskList.Count.ToShort()}]");
+                                }
+                            }
+                        });
+                    }
+                    else //出库
+                    {
+                        //获取当前堆垛机所有的放货点
+                        var list = srmDevice.GetDeliveryPoint().Where(v =>
+                        {
+                            //true:满足条件  false:不满足条件
+                            //返回结果为无货的设备  默认无货
+                            var res = true;
+                            //放货点是否有货
+                            if (v.Data.VoucherNo != v.Data2.VoucherNo) res = false;
+                            else if (v.Data3.Status.HasFlag(StationStatus.运行状态位)) res = false;
+                            else if (v.Data2.Status.HasFlag(IstationStatus.光电状态)) res = false;
+                            else if (v.Data2.Request == IstationRequest.堆垛机放货完成请求目标地址) res = false;
+                            else if (v.Data2.Tasknum > 10000) res = false;
+                            if (!v.Entity.Is(DF.SRM涂布放货)) return res;
+                            var devise = new List<StationDevice>();
+                            switch (v.Entity.CODE)
+                            {
+                                case "1283" or "1284":
+                                    devise = Device.Where(b => b.CODE is "1281" or "1282").Select(b => b.Create<StationDevice>()).ToList();
+                                    break;
+
+                                case "1290" or "1291" or "1292" or "1293":
+                                    devise = Device.Where(b => b.CODE is "1288" or "1289").Select(b => b.Create<StationDevice>()).ToList();
+                                    break;
+
+                                case "1299" or "1300" or "1301" or "1302":
+                                    devise = Device.Where(b => b.CODE is "1297" or "1298").Select(b => b.Create<StationDevice>()).ToList();
+                                    break;
+
+                                case "1308" or "1309" or "1310" or "1311":
+                                    devise = Device.Where(b => b.CODE is "1306" or "1307").Select(b => b.Create<StationDevice>()).ToList();
+                                    break;
+                            }
+
+                            if (!devise.Any()) return res;
+                            foreach (var stationDevice in devise)
+                            {
+                                //放货点是否有货
+                                if (stationDevice.Data3.Status.HasFlag(StationStatus.运行状态位)) res = false;
+                                else if (stationDevice.Data2.Status.HasFlag(IstationStatus.光电状态)) res = false;
+                                else if (stationDevice.Data2.Request == IstationRequest.堆垛机放货完成请求目标地址) res = false;
+                                else if (stationDevice.Data2.Tasknum > 10000) res = false;
+                            }
+
+                            return res;
+                        }).Select(v => v.Entity.CODE).ToList();
+
+                        //没有可用货位
+                        if (!list.Any()) return;
+
+                        //找到对应的设备组编号
+                        var groupList = Device.Where(v => v.IsDevGroup()).Where(v => v.DEVICEGROUP.Any(b => list.Contains(b.MEMBER.CODE))).Select(v => v.CODE).ToList();
+
+                        //堆垛机设备
+                        var srm = deviceCode;
+                        var finishTaskList = new List<FinishTaskList<SrmFork, Task>>();
+                        DB.Do(db =>
+                        {
+                            //堆垛机当前是否有正在执行的任务
+                            if (db.Default.Set<WCS_TASK>().Any(d => d.DEVICE == srm && d.STATUS == TaskStatus.堆垛机执行)) throw new WarnException($"[{deviceCode}]有正在执行的出库任务");
+
+                            //找出等待执行的出库任务
+                            var waitTask = db.Default.Set<WCS_TASK>().Where(v => v.STATUS == TaskStatus.新建)
+                                                          .Where(v => v.DEVICE == srm)
+                                                          .Where(v => v.TYPE == TaskType.出库)
+                                                          .Where(v => !db.Default.Set<WCS_TASK>().Any(d => d.DEVICE == srm && d.STATUS == TaskStatus.堆垛机执行))
+                                                          .Where(v => groupList.Contains(v.SRMSTATION)) //站台必须可用
+                                                          .ToList();
+
+                            //同时对结果进行排序,分组
+                            var outDepotGrouping = waitTask.OrderByDescending(v => v.Priority).ThenBy(v => v.CREATETIME)
+                                                           .GroupBy(v => v.TaskGroupKey)
+                                                           .FirstOrDefault().Select(v => v).ToList();
+                            if (outDepotGrouping == null) return; //用于解决Linq  Value cannot be null. (Parameter 'source')
+
+                            //获取一组任务
+                            var tasks = outDepotGrouping.Select(v => v.Create<Task>()).OrderBy(v => v.Col).ToArray();
+
+                            for (var i = 0; i < tasks.Count(); i++)
+                            {
+                                var item = tasks[i];
+                                var task = db.Default.Set<WCS_TASK>().Find(item.ID);
+                                var oldTaskStatus = task!.STATUS;
+                                task.STARTTIME = DateTime.Now;
+                                task.UPDATETIME = DateTime.Now;
+                                task.STATUS = TaskStatus.堆垛机执行;
+                                task.DEVICE = deviceCode;
+                                var fork = srmDevice.GetFork(item, i);
+                                //获取站台及下一个地址
+                                task.GetSrmStationAndaddNext(fork);
+                                var msg = "";
+                                msg = fork == SrmFork.货叉1 ? $"状态由[{oldTaskStatus}]变更为[{task.STATUS}][{srmDevice.Data.SLine_1}-{srmDevice.Data.SCol_1}-{srmDevice.Data.SLayer_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.VoucherNo_1}]" : $"状态由[{oldTaskStatus}]变更为[{task.STATUS}][{srmDevice.Data.SLine_2}-{srmDevice.Data.SCol_2}-{srmDevice.Data.SLayer_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.VoucherNo_2}]";
+                                task.CreateStatusLog(db, msg, this.GetType());
+                                item.SRMSTATION = task.SRMSTATION;
+                                finishTaskList.Add(new FinishTaskList<SrmFork, Task>(fork, item));
+                            }
+
+                            db.Default.SaveChanges();
+
+                            //此处只做标记,表示当前事务已经提交
+                            foreach (var finish in finishTaskList)
+                            {
+                                switch (finish.FinishCode)
+                                {
+                                    // 列数较小的放一工位
+                                    case SrmFork.货叉1:
+                                        obj.Data.TaskID_1 = finish.Station.ID;
+                                        break;
+                                    //列数较大的放二工位
+                                    case SrmFork.货叉2:
+                                        obj.Data.TaskID_2 = finish.Station.ID;
+                                        break;
+
+                                    default:
+                                        throw new ArgumentOutOfRangeException();
+                                }
+                            }
+                        });
+
+                        ////检查标记好的出库任务,并将出库任务下达至堆垛机
+                        DB.Do(db =>
+                        {
+                            //此处只做标记,表示当前事务已经提交
+                            foreach (var finish in finishTaskList)
+                            {
+                                var task = db.Default.Set<WCS_TASK>().Find(finish.Station.ID).Create<Task>();
+                                switch (finish.FinishCode)
+                                {
+                                    // 列数较小的放一工位
+                                    case SrmFork.货叉1:
+                                        obj.WriteTask1(task, (short)finishTaskList.Count);
+                                        break;
+                                    //列数较大的放二工位
+                                    case SrmFork.货叉2:
+                                        obj.WriteTask2(task, (short)finishTaskList.Count);
+                                        break;
+
+                                    default:
+                                        throw new ArgumentOutOfRangeException();
+                                }
+                            }
+                        });
+                    }
+                }
                 if (isTransfer.Count > 0) //防止因为无当前堆垛机移库任务导致无法执行其他类型任务
                 {
                     #region 移库
@@ -96,7 +343,7 @@ namespace WCS.Service.Works.SRM
                     DB.Do(db =>
                     {
                         //获取当前堆垛机未执行的任务的组ID
-                        var taskGroupKey = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == srmDevice.Entity.CODE && v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行).OrderBy(p => p.CREATETIME).FirstOrDefault()!.TaskGroupKey;
+                        var taskGroupKey = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行).OrderBy(p => p.CREATETIME).FirstOrDefault()!.TaskGroupKey;
                         //通过任务的组ID找到本组的所有任务
                         var tasks = db.Default.Set<WCS_TASK>().Where(v => v.TaskGroupKey == taskGroupKey);
 
@@ -115,7 +362,7 @@ namespace WCS.Service.Works.SRM
                             task.STARTTIME = DateTime.Now;
                             task.UPDATETIME = DateTime.Now;
                             task.STATUS = WCS.Entity.TaskStatus.堆垛机执行;
-                            task.DEVICE = srmDevice.Entity.CODE;
+                            task.DEVICE = deviceCode;
                             db.Default.SaveChanges();
                             Uploader.Upload(db);
                             task.CreateStatusLog(db, $"状态由[{oldTaskStatus}]变更为[{task.STATUS}]", this.GetType());
@@ -176,7 +423,7 @@ namespace WCS.Service.Works.SRM
                                                .OrderByDescending(v => v.Entity.CODE)
                                                .ToArray();
                     var finishTaskList = new List<FinishTaskList<int>>(); //成功分配货位的任务
-                    //取巷道
+                                                                          //取巷道
                     DB.Do(db =>
                     {
                         //检测有效任务数与实际任务是是否相等
@@ -201,7 +448,7 @@ namespace WCS.Service.Works.SRM
                             task.UPDATETIME = DateTime.Now;
                             task.STATUS = TaskStatus.堆垛机执行;
                             task.ADDRTO = $"{loc.Row}-{loc.Colomn}-{loc.Layer}";
-                            task.DEVICE = srmDevice.Entity.CODE;
+                            task.DEVICE = deviceCode;
                             task.TUNNEL = tunnel;
                             task.CreateStatusLog(db, $"状态由{oldTask}变更至{task.STATUS}", this.GetType());
                             finishTaskList.Add(new FinishTaskList<int>(task.ID, dev));
@@ -216,7 +463,7 @@ namespace WCS.Service.Works.SRM
                             var addTo = task!.ADDRTO.Split("-");
                             if (finish.Station.Entity.CODE == devise[0].Entity.CODE)  //一工位
                             {
-                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{srmDevice.Entity.CODE}]1工位-开始:[{srmDevice.Data.TaskID_1}][{srmDevice.Data.SLine_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.ECol_1}][{srmDevice.Data.ELayer_1}][{srmDevice.Data.VoucherNo_1}]--[{finishTaskList.Count.ToShort()}]");
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]1工位-开始:[{srmDevice.Data.TaskID_1}][{srmDevice.Data.SLine_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.ECol_1}][{srmDevice.Data.ELayer_1}][{srmDevice.Data.VoucherNo_1}]--[{finishTaskList.Count.ToShort()}]");
                                 srmDevice.Data.TaskID_1 = task.ID;
                                 srmDevice.Data.SLine_1 = finish.Station.Entity.CODE.ToShort();
                                 srmDevice.Data.SCol_1 = 0;
@@ -226,11 +473,11 @@ namespace WCS.Service.Works.SRM
                                 srmDevice.Data.ELayer_1 = addTo[2].ToShort();
                                 srmDevice.Data.RES1_1 = finishTaskList.Count.ToShort();
                                 srmDevice.Data.VoucherNo_1++;
-                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{srmDevice.Entity.CODE}]1工位-结束:[{srmDevice.Data.TaskID_1}][{srmDevice.Data.SLine_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.ECol_1}][{srmDevice.Data.ELayer_1}][{srmDevice.Data.VoucherNo_1}]--[{finishTaskList.Count.ToShort()}]");
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]1工位-结束:[{srmDevice.Data.TaskID_1}][{srmDevice.Data.SLine_1}][{srmDevice.Data.ELine_1}][{srmDevice.Data.ECol_1}][{srmDevice.Data.ELayer_1}][{srmDevice.Data.VoucherNo_1}]--[{finishTaskList.Count.ToShort()}]");
                             }
                             else if (finish.Station.Entity.CODE == devise[1].Entity.CODE)
                             {
-                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{srmDevice.Entity.CODE}]2工位-开始:[{srmDevice.Data.TaskID_2}][{srmDevice.Data.SLine_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.ECol_2}][{srmDevice.Data.ELayer_2}][{srmDevice.Data.VoucherNo_2}]--[{finishTaskList.Count.ToShort()}]");
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]2工位-开始:[{srmDevice.Data.TaskID_2}][{srmDevice.Data.SLine_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.ECol_2}][{srmDevice.Data.ELayer_2}][{srmDevice.Data.VoucherNo_2}]--[{finishTaskList.Count.ToShort()}]");
                                 srmDevice.Data.TaskID_2 = task.ID;
                                 srmDevice.Data.SLine_2 = finish.Station.Entity.CODE.ToShort();
                                 srmDevice.Data.SCol_2 = 0;
@@ -240,7 +487,7 @@ namespace WCS.Service.Works.SRM
                                 srmDevice.Data.ELayer_2 = addTo[2].ToShort();
                                 srmDevice.Data.RES1_2 = finishTaskList.Count.ToShort();
                                 srmDevice.Data.VoucherNo_2++;
-                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{srmDevice.Entity.CODE}]2工位-结束:[{srmDevice.Data.TaskID_2}][{srmDevice.Data.SLine_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.ECol_2}][{srmDevice.Data.ELayer_2}][{srmDevice.Data.VoucherNo_2}]--[{finishTaskList.Count.ToShort()}]");
+                                InfoLog.INFO_SRMINFO($"入库--写入堆垛机[{deviceCode}]2工位-结束:[{srmDevice.Data.TaskID_2}][{srmDevice.Data.SLine_2}][{srmDevice.Data.ELine_2}][{srmDevice.Data.ECol_2}][{srmDevice.Data.ELayer_2}][{srmDevice.Data.VoucherNo_2}]--[{finishTaskList.Count.ToShort()}]");
                             }
                         }
                     });
@@ -311,7 +558,7 @@ namespace WCS.Service.Works.SRM
                     var groupList = Device.Where(v => v.IsDevGroup()).Where(v => v.DEVICEGROUP.Any(b => list.Contains(b.MEMBER.CODE))).Select(v => v.CODE).ToList();
 
                     //堆垛机设备
-                    var srm = srmDevice.Entity.CODE;
+                    var srm = deviceCode;
                     var finishTaskList = new List<FinishTaskList<SrmFork, Task>>();
                     DB.Do(db =>
                     {
@@ -370,7 +617,7 @@ namespace WCS.Service.Works.SRM
                             task.STARTTIME = DateTime.Now;
                             task.UPDATETIME = DateTime.Now;
                             task.STATUS = WCS.Entity.TaskStatus.堆垛机执行;
-                            task.DEVICE = srmDevice.Entity.CODE;
+                            task.DEVICE = deviceCode;
                             task.TaskGroupKey = tasks.Length switch
                             {
                                 1 => $"{tasks[0].ID}_0",

+ 4 - 0
Projects/永冠OPP/WCS.Service/Works/Station/涂布出库.cs

@@ -138,6 +138,10 @@ namespace WCS.Service.Works.Station
                             var tasks = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey);
                             if (tasks != devise.Count) throw new WarnException($"可执行任务数{devise.Count},实际任务数{tasks}");
 
+                            //问题,要怎么确定目标巷道的货物
+
+
+
                             task.ADDRNEXT = "G1";
                             task.CreateStatusLog(db, $"分配目标地址{task.ADDRNEXT}", this.GetType());
                             finishTaskList.Add(new FinishTaskList<int>(task.ID, dev.Station));