Explorar el Código

移除业务处理及数据库非查询操作

林豪 左 hace 2 años
padre
commit
fcefaecf31

+ 1 - 1
OPP WCS.sln

@@ -26,7 +26,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 		.editorconfig = .editorconfig
 	EndProjectSection
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WCS.Service", "Projects\永冠OPP\WCS.Service\WCS.Service.csproj", "{0C1638C8-68C1-4493-A731-186E58CEC4F0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WCS.DataCollectionService", "Projects\永冠OPP\WCS.Service\WCS.DataCollectionService.csproj", "{0C1638C8-68C1-4493-A731-186E58CEC4F0}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logs", "Logs\Logs.csproj", "{31B6E0FC-524C-4B52-9088-6EA4690E6B36}"
 EndProject

+ 0 - 10
Projects/永冠OPP/WCS.Service/DeviceExtentions.cs

@@ -134,15 +134,7 @@ namespace WCS.Service
             return source.PROTOCOLS.Any(v => v.DB.PROTOCOL == typeof(ISRM520).AssemblyQualifiedName);
         }
 
-        //public static bool IsRobot(this WCS_DEVICE source)
-        //{
-        //    return source.PROTOCOLS.Any(v => v.DB.PROTOCOL == typeof(IRobot).AssemblyQualifiedName);
-        //}
 
-        //public static bool IsRobotStation(this WCS_DEVICE source)
-        //{
-        //    return source.PROTOCOLS.Any(v => v.DB.PROTOCOL == typeof(IRobotStation).AssemblyQualifiedName);
-        //}
 
         public static bool IsTunnel(this WCS_DEVICE source)
         {
@@ -156,8 +148,6 @@ namespace WCS.Service
         {
             var q = db.Default.Set<WCS_Station520>().Where(v => v.ISLAST && v.Tasknum == source.ID).Select(v => new { type = 1, v.DEVICE.CODE });
             q = q.Union(db.Default.Set<WCS_RGV521>().Where(v => v.ISLAST && (v.TaskID_1 == source.ID || v.TaskID_2 == source.ID)).Select(v => new { type = 2, v.DEVICE.CODE }));
-            //q = q.Union(db.Default.Set<WCS_SC521>().Where(v => v.ISLAST && v.TaskID == source.ID).Select(v => new { type = 2, v.DEVICE.CODE }));
-            //q = q.Union(db.Default.Set<WCS_Robot>().Where(v => v.ISLAST && v.TaskID == source.ID).Select(v => new { type = 2, v.DEVICE.CODE }));
 
             var res = q.OrderBy(v => v.type).FirstOrDefault();
             if (res == null)

+ 0 - 1185
Projects/永冠OPP/WCS.Service/Extensions/DeviceExtension.cs

@@ -1,1185 +0,0 @@
-using DBHelper;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.RGV;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Extensions
-{
-    /// <summary>
-    /// 输送机设备组
-    /// </summary>
-    public class StationDeviceGroup : DeviceGroup<IStation520, IStation521, IStation523>
-    {
-        /// <summary>
-        /// 当前设备可用的RGV
-        /// </summary>
-        private static List<RGVDevice> AllRGVList;
-
-        static StationDeviceGroup()
-        {
-            AllRGVList = Device.Where(v => v.IsRGV() && v.CODE != "RGV8").Select(v => v.Create<RGVDevice>()).ToList();
-        }
-
-        public StationDeviceGroup(WCS_DEVICE entity) : base(entity)
-        {
-        }
-
-        /// <summary>
-        /// 执行输送机设备组任务 单例锁
-        /// </summary>
-        /// <param name="act"></param>
-        public void EX(Action<StationDeviceGroup> act)
-        {
-            var key = $"WCS:Lock:{Entity.CODE}";
-            try
-            {
-                if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"[{Entity.CODE}]--触发并发管控");
-                ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                act(this);
-            }
-            catch (DoException ex)
-            {
-                ex.DoExceptionEX(Entity);
-            }
-            catch (WarnException ex)
-            {
-                ex.WarnExceptionEX(Entity);
-            }
-            catch (Exception ex)
-            {
-                ex.ExceptionEx(Entity);
-            }
-            finally
-            {
-                ProtocolProxy.YG150Redis.Del(key);
-            }
-        }
-
-        /// <summary>
-        /// 当前设备可用的RGV
-        /// </summary>
-        public List<RGVDevice> RgvList
-        {
-            get
-            {
-                return AllRGVList.Where(v => v.LocationList.Any(p => p.Entity == Entity) && v.Data2.WorkMode != 0).ToList();
-            }
-        }
-
-        /// <summary>
-        /// 当前设备环穿组
-        /// </summary>
-        private List<StationLocation> LoncationList
-        {
-            get
-            {
-                var dev = StationLocation.ALLlocations.FirstOrDefault(v => v.Station == Entity.CODE);
-                return StationLocation.ALLlocations.Where(v => v.PLC == dev.PLC).ToList();
-            }
-        }
-
-        /// <summary>
-        /// 设备组自身的位置
-        /// </summary>
-        public float Position
-        {
-            get
-            {
-                return StationLocation.ALLlocations.FirstOrDefault(v => v.Station == Entity.CODE).Location;
-            }
-        }
-
-        /// <summary>
-        /// 设备组所在环穿的总长度
-        /// </summary>
-        public float Length
-        {
-            get
-            {
-                return StationLocation.ALLlocations.FirstOrDefault(v => v.Station == Entity.CODE).Length;
-            }
-        }
-
-        /// <summary>
-        /// 设备组是否满足任务执行条件
-        /// </summary>
-        /// <param name="type">给当前设备组下发任务时需要的请求</param>
-        /// <returns>true:不满足执行条件需要进行停止执行  false:表示满足条件不需要停止执行 </returns>
-        /// <exception cref="Exception"></exception>
-        public void WhetherToExecute(IstationRequest type = IstationRequest.无)
-        {
-            foreach (var item in Items)
-            {
-                if (item.Data.VoucherNo != item.Data2.VoucherNo) throw new WarnException($"等待{item.Entity.CODE}执行任务{item.Data.Tasknum},凭证号不一致");
-                if (item.Data3.Status.HasFlag(StationStatus.运行状态位)) throw new DoException($"{item.Entity.CODE}运行中");
-                if (!item.Data2.Status.HasFlag(IstationStatus.光电状态)) throw new DoException($"[{item.Entity.CODE}]无光电");
-            }
-        }
-
-        /// <summary>
-        /// 获取设备组中需要取货的设备
-        /// </summary>
-        /// <returns></returns>
-        public List<Device<IStation520, IStation521, IStation523>> RGVGetTaskedDevice()
-        {
-            var a = Items.Where(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum > 10000)
-                        .Where(v => v.Entity.CODE.ToShort() != v.Data2.Goodsend && v.Data2.Goodsend != 0)
-                        .ToList();
-            return a.Count == 0 ? null : a;
-        }
-
-        /// <summary>
-        /// 是否可以取货
-        /// </summary>
-        /// <returns></returns>
-        public bool IsPickUp(RGVDevice rgvDevice)
-        {
-            if (Entity.CODE is "G2" or "G3") return true;
-            var dCount = Device.Where(v => v.CODE is "G1" or "G1340" or "G1337").Select(v => v.Create<StationDeviceGroup>()).Count(v =>
-            {
-                var count = v.Items.Count(v => !v.Data3.Status.HasFlag(StationStatus.运行状态位) && !v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000
-                  && v.Data3.Status.HasFlag(StationStatus.自动));
-                return count == 2 ? true : false;
-            });
-            var rCount = rgvDevice.RGVList.Count(v => v.Data.DestPosition_1 == 1);
-            return rCount < dCount;
-        }
-
-        /// <summary>
-        /// 入库位置获取需要生产任务的设备及条码信息
-        /// </summary>
-        /// <returns></returns>
-        public List<FinishTaskList<string>> GetBcrValid()
-        {
-            var list = new List<FinishTaskList<string>>();
-
-            //获取需要执行的设备信息
-            foreach (var dev in Items)
-            {
-                if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                {
-                    InfoLog.INFO_INFO($"{dev.Entity.CODE}--没有光电");
-                    continue;
-                }
-                if (dev.Data2.Request != IstationRequest.扫码入库)
-                {
-                    InfoLog.INFO_WarnDb($"{dev.Entity.CODE}--有光电没有扫码入库请求--1", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                    continue;
-                };
-                if (dev.Data2.Tasknum > 10000)
-                {
-                    InfoLog.INFO_WarnDb($"{dev.Entity.CODE}--有光电有请求,但已有任务号", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                    continue;
-                }
-
-                var bcr = dev.Entity.BCR();
-                var barcode = bcr.Content.Trim('\r');
-                if (barcode == "")
-                {
-                    InfoLog.INFO_WarnDb($"{dev.Entity.CODE}--扫码失败,内容为空", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                    continue;
-                };
-
-                list.Add(new FinishTaskList<string>(barcode, dev.Entity.Create<StationDevice>()));
-            }
-            return list;
-        }
-
-        /// <summary>
-        /// 获取下一个地址的有效设备
-        /// </summary>
-        /// <returns></returns>
-        public List<FinishTaskList<string>> GetAddressValid()
-        {
-            var list = new List<FinishTaskList<string>>();
-
-            //获取需要执行的设备信息
-            foreach (var dev in Items)
-            {
-                if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                {
-                    InfoLog.INFO_INFO($"{dev.Entity.CODE}--没有光电");
-                    continue;
-                }
-                if (dev.Data2.Request != IstationRequest.请求分配目标地址)
-                {
-                    InfoLog.INFO_INFO($"{dev.Entity.CODE}--有光电没有分配目标地址请求--2");
-                    continue;
-                };
-                if (dev.Data2.Tasknum < 10000)
-                {
-                    InfoLog.INFO_WarnDb($"{dev.Entity.CODE}--有光电有请求没有任务号", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                    continue;
-                }
-
-                list.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-            }
-            return list;
-        }
-
-        /// <summary>
-        /// 最近的RGV
-        /// </summary>
-        /// <returns></returns>
-        public RGVDevice RecentRGV()
-        {
-            return RgvList.OrderBy(v => v.Distance(this)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 计算目标RGV与站台自身的距离
-        /// </summary>
-        /// <param name="rgv"></param>
-        /// <returns></returns>
-        public float Distance(RGVDevice rgv)
-        {
-            return DevEX.Distance(Position, rgv.Position, Length);
-        }
-
-        /// <summary>
-        /// 计算两个站台之间的距离
-        /// </summary>
-        /// <param name="rgv"></param>
-        /// <returns></returns>
-        public float Distance(StationDeviceGroup dev)
-        {
-            return DevEX.Distance(Position, dev.Position, Length);
-        }
-
-        /// <summary>
-        /// 当前RGV
-        /// </summary>
-        /// <returns></returns>
-        public RGVDevice CurrentRGV()
-        {
-            //RGV与站台距离误差为 正负50
-            var max = Position + 500;
-            var min = Position - 500;
-            return RgvList?.FirstOrDefault(v => v.Data2.Position < max && v.Data2.Position > min);
-        }
-
-        /// <summary>
-        /// 是否需要RGV
-        /// </summary>
-        /// <returns>true:需要RGV false:不需要RGV</returns>
-        public bool NeedRgv()
-        {
-            var rgvs = Device.Where(v => v.IsRGV()).Select(v => v.Device<IRGV521>());
-            var code = Entity.CODE.Replace("G", "").ToShort();
-            if (rgvs.Any(v => v.Data.DestPosition_1 == code && v.Data.SystemStatus != RGVRunStatus.空闲))
-                throw new WarnException("已有RGV执行中");
-            foreach (var item in Items)
-            {
-                if (item.Data3.Status.HasFlag(StationStatus.运行状态位)) return false;
-                if (!item.Data2.Status.HasFlag(IstationStatus.光电状态)) return false;
-            }
-
-            return true;
-        }
-
-        /// <summary>
-        /// BCR 站点是否被禁止
-        /// </summary>
-        /// <returns></returns>
-        public bool BcrStationIsForbid()
-        {
-            var res = true;
-            var config = ProtocolProxy.YGWMS150Redis.Get("ForbidTubuEnter").Split(",");
-            if (config.Contains(Entity.CODE))
-            {
-                InfoLog.INFO_WarnDb("当前入库口已被禁用,请联系机修人员了解具体情况", Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常);
-                res = false;
-            };
-            return res;
-        }
-    }
-
-    /// <summary>
-    /// 输送机设备
-    /// </summary>
-    public class StationDevice : Device<IStation520, IStation521, IStation523>
-    {
-        public StationDevice(WCS_DEVICE entity) : base(entity)
-        {
-        }
-
-        /// <summary>
-        /// 设备组是否满足任务执行条件
-        /// </summary>
-        /// <param name="type">给当前设备组下发任务时需要的请求</param>
-        /// <returns>true:不满足执行条件需要进行停止执行  false:表示满足条件不需要停止执行 </returns>
-        /// <exception cref="Exception"></exception>
-        public void WhetherToExecute(IstationRequest type = IstationRequest.无)
-        {
-            //正在运行
-            if (Data3.Status.HasFlag(StationStatus.运行状态位)) throw new DoException("运行中");
-            //上一次的任务还未执行
-            if (Data.VoucherNo != Data2.VoucherNo)
-                throw new WarnException($"等待任务[{Data2.Tasknum}]执行");
-            //没有光电
-            if (!Data2.Status.HasFlag(IstationStatus.光电状态)) throw new DoException("无光电"); ;
-            //没有任务号
-            switch (type)
-            {
-                case IstationRequest.无:
-                    if (Data2.Tasknum < 10000 && Data.Tasknum < 10000)
-                        throw new WarnException($"设备无任务");
-                    break;
-
-                case IstationRequest.扫码入库:
-                    if (Data2.Tasknum > 10000 && Data.Tasknum > 10000)
-                        throw new WarnException($"设备已有任务任务");
-                    break;
-
-                case IstationRequest.堆垛机放货完成请求目标地址:
-                    if (Data2.Tasknum < 10000 && Data.Tasknum < 10000)
-                        throw new WarnException($"设备无任务信息");
-                    break;
-
-                case IstationRequest.请求分配目标地址:
-                    if (Data2.Tasknum < 10000 && Data.Tasknum < 10000)
-                        throw new WarnException($"设备无任务信息");
-                    break;
-            }
-            //没有请求
-            if (type != IstationRequest.无 && Data2.Request != type)
-                throw new WarnException($"有光电无{type}请求");
-        }
-
-        /// <summary>
-        /// 执行输送机任务 单例锁
-        /// </summary>
-        /// <param name="act"></param>
-        public void EX(Action<StationDevice> act)
-        {
-            var key = $"WCS:Lock:{Entity.CODE}";
-
-            try
-            {
-                if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"[{Entity.CODE}]--触发并发管控");
-                ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                act(this);
-            }
-            catch (DoException ex)
-            {
-                ex.DoExceptionEX(Entity);
-            }
-            catch (WarnException ex)
-            {
-                ex.WarnExceptionEX(Entity);
-            }
-            catch (Exception ex)
-            {
-                ex.ExceptionEx(Entity);
-            }
-            finally
-            {
-                ProtocolProxy.YG150Redis.Del(key);
-            }
-        }
-    }
-
-    /// <summary>
-    /// RGV设备
-    /// </summary>
-    public class RGVDevice : Device<IRGV520, IRGV521, IRGV523>
-    {
-        static RGVDevice()
-        {
-            AllRGVList = Device.Where(v => v.IsRGV() && v.CODE != "RGV8").Select(v => v.Create<RGVDevice>()).ToList();
-        }
-
-        public RGVDevice(WCS_DEVICE entity) : base(entity)
-        {
-        }
-
-        /// <summary>
-        /// 所有环穿RGV
-        /// </summary>
-        private static List<RGVDevice> AllRGVList { get; set; }
-
-        /// <summary>
-        /// 与当前RGV处于同一环穿的RGV
-        /// </summary>
-        public List<RGVDevice> RGVList
-        {
-            get
-            {
-                //利用WorkMode来排除的环穿维护设备
-                return AllRGVList.Where(v => v.Entity.PROTOCOLS.Any(d => Entity.PROTOCOLS.Any(e => e.DB.PLC.IP == d.DB.PLC.IP)))
-                    .Where(v => v.Data2.WorkMode != 0)
-                    .Where(v => v.Entity.CODE != Entity.CODE).ToList();
-            }
-        }
-
-        /// <summary>
-        /// RGV当前位置
-        /// </summary>
-        public float Position
-        {
-            get
-            {
-                return Data2.Position;
-            }
-        }
-
-        /// <summary>
-        /// 与当前RGV处于同一环穿的站台
-        /// </summary>
-        public List<StationDeviceGroup> LocationList
-        {
-            get
-            {
-                return StationLocation.ALLlocations.Where(v => Entity.PROTOCOLS.Any(p => p.DB.PLC.CODE == v.PLC))
-                                      .Select(v => Device.Find(v.Station).Create<StationDeviceGroup>()).ToList();
-            }
-        }
-
-        /// <summary>
-        /// 总长度
-        /// </summary>
-        public float Length
-        {
-            get
-            {
-                return LocationList.FirstOrDefault().Length;
-            }
-        }
-
-        /// <summary>
-        /// 执行RGV任务 单例锁
-        /// </summary>
-        /// <param name="act"></param>
-        public void EX(Action<RGVDevice> act)
-        {
-            var key = $"WCS:Lock:{Entity.CODE}";
-
-            try
-            {
-                if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"[{Entity.CODE}]--触发并发管控");
-                ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                act(this);
-            }
-            catch (DoException ex)
-            {
-                ex.DoExceptionEX(Entity);
-            }
-            catch (WarnException ex)
-            {
-                ex.WarnExceptionEX(Entity);
-            }
-            catch (Exception ex)
-            {
-                ex.ExceptionEx(Entity);
-            }
-            finally
-            {
-                ProtocolProxy.YG150Redis.Del(key);
-            }
-        }
-
-        /// <summary>
-        /// 获取前一个取货点
-        /// </summary>
-        /// <returns></returns>
-        public StationDeviceGroup BeforeStation()
-        {
-            var a = LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货设备组) || v.Entity.Is(DF.BOPPRGV取货设备组));
-            return LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货设备组) || v.Entity.Is(DF.BOPPRGV取货设备组) && v.Entity.CODE != this.CurrentStation().Entity.CODE).OrderBy(v => Distance(v)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 前一个RGV
-        /// </summary>
-        /// <returns></returns>
-        public RGVDevice Before()
-        {
-            //按照位置排序
-            var arr = RGVList.OrderBy(v => v.Position);
-            var rgv = arr.FirstOrDefault(v => v.Position > Position);
-            if (rgv == null)
-                rgv = arr.LastOrDefault(v => v.Position < Position);
-            return rgv;
-        }
-
-        /// <summary>
-        /// 后一个RGV
-        /// </summary>
-        /// <returns></returns>
-        public RGVDevice After()
-        {
-            //到当前RGV最近的一个RGV
-            return RGVList.OrderBy(v => v.Distance(this)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取当前所在的取货站台
-        /// </summary>
-        /// <returns></returns>
-        public StationDeviceGroup CurrentStation()
-        {
-            return LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货设备组) || v.Entity.Is(DF.涂布RGV放货设备组) || v.Entity.Is(DF.BOPPRGV取货设备组) || v.Entity.Is(DF.BOPPRGV放货设备组)).Where(v =>
-                {
-                    //RGV与站台距离误差为 正负50500
-                    var max = v.Position + 500;
-                    var min = v.Position - 500;
-                    return Data2.Position < max && Data2.Position > min;
-                }).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 计算当前RGV与指定RGV之间的距离
-        /// </summary>
-        /// <param name="rgv"></param>
-        /// <returns></returns>
-        public float Distance(RGVDevice rgv)
-        {
-            //return Math.Abs((Position - rgv.Position + Length) % Length);
-            return DevEX.Distance(Position, rgv.Position, Length);
-        }
-
-        /// <summary>
-        /// 计算当前RGV与指定站台之间的距离
-        /// </summary>
-        /// <param name="after"></param>
-        /// <returns></returns>
-        public float Distance(StationDeviceGroup after)
-        {
-            if (after == null) throw new WarnException($"不是一个有效的StationDeviceGroup,{Entity.CODE}");
-            return DevEX.Distance(Position, after.Position, Length);
-        }
-
-        /// <summary>
-        /// 是否需要执行放货任务
-        /// </summary>
-        /// <returns></returns>
-        public bool IsPut()
-        {
-            if (Data2.TaskType_1 != RGVTaskType.取货) return false;
-            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站)) return false;
-            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.任务完成)) return false;
-            if (!Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) return false;
-            return true;
-        }
-
-        /// <summary>
-        /// 写入移动任务
-        /// </summary>
-        /// <param name="addr">目标地址</param>
-        public void Move(StationDeviceGroup addr)
-        {
-            if (Data.TaskType_1 == RGVTaskType.取货) throw new WarnException($"当前有{Data.TaskType_1}任务,无法执行移动任务");
-            if (Data2.WorkMode != RGVMode.自动) throw new WarnException($"RGV状态{Data2.WorkMode},无法执行移动任务");
-            if (Data2.SystemStatus != RGVRunStatus.空闲) throw new WarnException($"rgv状态为{Data2.SystemStatus},无法执行移动任务");
-            if (Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV有光电,无法执行移动任务");
-            if (Data2.TaskID_1 == addr.Entity.CODE.GetShortCode() && Data.TaskType_1 == RGVTaskType.移动)
-            {
-                InfoLog.INFO_RGVINFO($"{Entity.CODE}]--已有目标地址相同的移动任务");
-                return;
-            }
-            InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV移动任务-开始:{Data.TaskID_1},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-
-            Data.TaskID_1 = addr.Entity.CODE.GetShortCode();
-            Data.TaskType_1 = RGVTaskType.移动;
-            Data.DestPosition_1 = addr.Entity.CODE.GetShortCode();
-            Data.Trigger_1++;
-            InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV移动任务-结束:{Data.TaskID_1},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-        }
-
-        /// <summary>
-        /// 写入取货任务
-        /// </summary>
-        /// <param name="addr">目标地址</param>
-        public void Pick(StationDeviceGroup addr, int task1, int task2)
-        {
-            InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV取货任务-开始:{Data.TaskID_1},{Data.TaskID_2},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-            Data.TaskType_1 = RGVTaskType.取货;
-            Data.DestPosition_1 = addr.Entity.CODE.GetShortCode();
-            Data.TaskID_1 = task1;
-            Data.TaskID_2 = task2;
-            Data.Trigger_1++;
-            InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV取货任务-结束:{Data.TaskID_1},{Data.TaskID_2},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-        }
-
-        ///// <summary>
-        ///// 写入取货任务
-        ///// </summary>
-        ///// <param name="addr">目标地址</param>
-        //public void Pick(StationDeviceGroup addr, int task1 = 0, int task2 = 0)
-        //{
-        //    InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV取货任务-开始:{Data.TaskID_1},{Data.TaskID_2},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-        //    Data.TaskType_1 = RGVTaskType.取货;
-        //    Data.DestPosition_1 = addr.Entity.CODE.GetShortCode();
-        //    if (task1 != 0) Data.TaskID_1 = task1;
-        //    if (task2 != 0) Data.TaskID_2 = task2;
-        //    Data.Trigger_1++;
-        //    InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV取货任务-结束:{Data.TaskID_1},{Data.TaskID_2},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-        //}
-
-        /// <summary>
-        /// 写入放货任务
-        /// </summary>
-        /// <param name="addr">目标地址</param>
-        public void Put(StationDeviceGroup addr, int task1 = 0, int task2 = 0)
-        {
-            InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV放货任务-开始:{Data.TaskID_1},{Data.TaskID_2},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-            Data.TaskType_1 = RGVTaskType.放货;
-            Data.DestPosition_1 = addr.Entity.CODE.GetShortCode();
-            if (task1 != 0) Data.TaskID_1 = task1;
-            if (task2 != 0) Data.TaskID_2 = task2;
-            Data.Trigger_1++;
-            InfoLog.INFO_RGVINFO($"[{Entity.CODE}]--写入RGV放货任务-结束:{Data.TaskID_1},{Data.TaskID_2},{Data.TaskType_1},{Data.DestPosition_1},{Data.Trigger_1}");
-        }
-
-        /// <summary>
-        /// 筛选出所有与当前RGV距离小于指定长度的RGV
-        /// </summary>
-        /// <param name="distance">指定长度</param>
-        /// <returns></returns>
-        public RGVDevice[] RgvAfter(float distance)
-        {
-            return RGVList.Where(v => Distance(v) < distance).ToArray();
-        }
-
-        /// <summary>
-        /// 当前RGV是否有拦住指定RGV
-        /// </summary>
-        /// <param name="rgv">RGV</param>
-        /// <returns></returns>
-        public bool StopedByMe(RGVDevice rgv)
-        {
-            //目标站台
-            var target = rgv.Data2.DestPosition_1;
-            //获取目标站台的设备组信息
-            var station = Device.Find($"G{target}").Create<StationDeviceGroup>();
-
-            if (station.Distance(rgv) < 5000) return false;
-
-            //当前RGV与目标站台的距离小于传入RGV到达目标站台的距离
-            return (this.Distance(station) < rgv.Distance(station)) || station.CurrentRGV()?.Entity.CODE == this.Entity.CODE;
-        }
-
-        /// <summary>
-        /// 获取当前RGV的下一个站台,即距离最近的一个站台
-        /// </summary>
-        /// <returns></returns>
-        public StationDeviceGroup NextStation()
-        {
-            //先取当前RGV与所有站台的距离
-            var dev = LocationList.OrderBy(v => v.Distance(this)).FirstOrDefault();
-            return dev;
-        }
-    }
-
-    /// <summary>
-    /// 堆垛机设备
-    /// </summary>
-    public class SRMDevice : Device<ISRM520, ISRM521, ISRM537>
-    {
-        public SRMDevice(WCS_DEVICE entity) : base(entity)
-        {
-        }
-
-        /// <summary>
-        /// 获取放货点
-        /// </summary>
-        public List<StationDevice> GetDeliveryPoint()
-        {
-            return Entity.ROUTES.Select(v => v.NEXT) //巷道
-                                .SelectMany(v => v.ROUTES.Select(d => d.NEXT)) //放货点
-                                .Where(v => v.IsConv()) //必须是输送线
-                                .Select(v => v.Create<StationDevice>()).ToList();
-        }
-
-        /// <summary>
-        /// 获取取货点
-        /// </summary>
-        public List<StationDevice> GetPickPoint()
-        {
-            return Device.Where(v => v.Is(DF.SRM二级品取货) || v.Is(DF.SRM涂布取货) || v.Is(DF.SRMBOPP取货))
-                         .Where(v => v.ROUTES.Any(p => p.NEXT.ROUTES.Any(d => d.NEXT == Entity)))
-                         .Select(v => v.Create<StationDevice>())
-                         .ToList();
-        }
-
-        /// <summary>
-        /// 处理完成任务
-        /// </summary>
-        public void FinishedTaskHandle()
-        {
-            WCS_TASK task = new WCS_TASK();
-
-            DB.Do(db =>
-            {
-                var taskIds = new List<int>() { Data2.FinishedTask_1, Data2.FinishedTask_2 }.ToArray();
-
-                for (int i = 0; i < taskIds.Length; i++)
-                {
-                    //判断当前工位是否有完成任务
-                    if (taskIds[i] == 0) continue;
-                    task = db.Default.Set<WCS_TASK>().Single(v => taskIds[i] == v.ID);
-                    if (task.STATUS != TaskStatus.堆垛机执行 && task.STATUS != TaskStatus.堆垛机完成)
-                    {
-                        InfoLog.INFO_WarnDb($"任务{task.ID},状态位{task.STATUS}", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    };
-
-                    if (task.STATUS == TaskStatus.堆垛机完成)
-                    {
-                        if (i == 0)
-                        {
-                            Data.FinishedACK_1 = 1;
-                            Data.TaskID_1 = 0;
-                        }
-                        else
-                        {
-                            Data.FinishedACK_2 = 1;
-                            Data.TaskID_2 = 0;
-                        }
-
-                        throw new DoException("二次处理堆垛机完成任务");
-                    }
-
-                    switch (task.TYPE)
-                    {
-                        case TaskType.入库:
-                            task.ENDTIME = DateTime.Now;
-                            task.STATUS = TaskStatus.已完成;
-                            task.UPDATETIME = DateTime.Now;
-                            break;
-
-                        case TaskType.出库:
-                            task.STATUS = TaskStatus.堆垛机完成;
-                            task.UPDATETIME = DateTime.Now;
-                            break;
-
-                        case TaskType.移库:
-                            {
-                                if (task.STATUS == TaskStatus.堆垛机执行)
-                                {
-                                    task.STATUS = TaskStatus.已完成;
-                                    task.UPDATETIME = DateTime.Now;
-                                }
-
-                                break;
-                            }
-                        case TaskType.倒库:
-                            if (task.DEVICEDL == Entity.CODE)
-                            {
-                                task.STATUS = TaskStatus.已完成;
-                                task.UPDATETIME = DateTime.Now;
-                            }
-                            else
-                            {
-                                task.STATUS = TaskStatus.堆垛机完成;
-                                task.UPDATETIME = DateTime.Now;
-                            }
-
-                            break;
-
-                        default:
-                            throw new Exception($"[{Entity.CODE}]任务类型错误,{task.ID}");
-                    }
-
-                    task.CreateStatusLog(db, $"堆垛机完成任务", this.GetType());
-                }
-                db.Default.SaveChanges();
-            });
-
-            DB.Do(db =>
-            {
-                var taskIds = new List<int>() { Data2.FinishedTask_1, Data2.FinishedTask_2 }.ToArray();
-
-                for (int i = 0; i < taskIds.Length; i++)
-                {
-                    //判断当前工位是否有完成任务
-                    if (taskIds[i] == 0) continue;
-                    //获取当前工位的目标地址
-                    task = db.Default.Set<WCS_TASK>().Single(v => taskIds[i] == v.ID);
-
-                    if (i == 0)
-                    {
-                        Data.FinishedACK_1 = 1;
-                        Data.TaskID_1 = 0;
-                    }
-                    else
-                    {
-                        Data.FinishedACK_2 = 1;
-                        Data.TaskID_2 = 0;
-                    }
-                }
-            });
-        }
-
-        /// <summary>
-        /// 执行堆垛机任务 单例锁
-        /// </summary>
-        /// <param name="act"></param>
-        public void EX(Action<SRMDevice> act)
-        {
-            var key = $"WCS:Lock:{Entity.CODE}";
-
-            try
-            {
-                if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"[{Entity.CODE}]--触发并发管控");
-                ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                act(this);
-            }
-            catch (DoException ex)
-            {
-                ex.DoExceptionEX(Entity);
-            }
-            catch (WarnException ex)
-            {
-                ex.WarnExceptionEX(Entity);
-            }
-            catch (Exception ex)
-            {
-                ex.ExceptionEx(Entity);
-            }
-            finally
-            {
-                ProtocolProxy.YG150Redis.Del(key);
-            }
-        }
-
-        /// <summary>
-        /// 执行出库任务 出库单例锁
-        /// </summary>
-        /// <param name="act"></param>
-        public void EXOutStock(Action<SRMDevice> act)
-        {
-            var key = "WCS:Lock:";
-            try
-            {
-                if (Entity.CODE == "SRM3" || Entity.CODE == "SRM4")
-                {
-                    key += "SRM3-SRM4-Out";
-                    if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"触发出库并发管控--[{Entity.CODE}]");
-                    ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                }
-                if (Entity.CODE == "SRM5" || Entity.CODE == "SRM6")
-                {
-                    key += "SRM5-SRM6-Out";
-                    if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"触发出库并发管控--[{Entity.CODE}]");
-                    ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                }
-
-                if (Entity.CODE == "SRM7" || Entity.CODE == "SRM8")
-                {
-                    key += "SRM7-SRM8-Out";
-                    if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"触发出库并发管控--[{Entity.CODE}]");
-                    ProtocolProxy.YG150Redis.Set(key, Entity.CODE);
-                }
-
-                act(this);
-            }
-            finally
-            {
-                if (Entity.CODE == "SRM3" || Entity.CODE == "SRM4") ProtocolProxy.YG150Redis.Del($"{key}SRM3-SRM4-Out");
-                if (Entity.CODE == "SRM5" || Entity.CODE == "SRM6") ProtocolProxy.YG150Redis.Del($"{key}SRM5-SRM6-Out");
-                if (Entity.CODE == "SRM7" || Entity.CODE == "SRM8") ProtocolProxy.YG150Redis.Del($"{key}SRM7-SRM8-Out");
-            }
-        }
-
-        /// <summary>
-        /// 一工位写任务
-        /// </summary>
-        /// <param name="task"></param>
-        /// <param name="goodsnum">货物数量</param>
-        public void WriteTask1(Task task, short goodsnum)
-        {
-            InfoLog.INFO_SRMINFO($"出库--写入堆垛机[{Entity.CODE}]1工位-开始:[{Data.TaskID_1}][{Data.SLine_1}][{Data.SCol_1}][{Data.SLayer_1}][{Data.ELine_1}][{Data.VoucherNo_1}]--[{Data.RES1_1}]");
-            Data.TaskID_1 = task.ID;
-            Data.SLine_1 = task.Line;
-            Data.SCol_1 = task.Col;
-            Data.SLayer_1 = task.Layer;
-
-            if (task.TYPE == TaskType.移库)
-            {
-                Data.ELine_1 = task.EndLine;
-                Data.ECol_1 = task.EndCol;
-                Data.ELayer_1 = task.EndLayer;
-            }
-            else
-            {
-                Data.ELine_1 = task.SRMSTATION.ToShort();
-                Data.ECol_1 = 0;
-                Data.ELayer_1 = 0;
-            }
-
-            Data.RES1_1 = goodsnum;
-            Data.VoucherNo_1++;
-            InfoLog.INFO_SRMINFO($"出库--写入堆垛机[{Entity.CODE}]1工位-结束:[{Data.TaskID_1}][{Data.SLine_1}][{Data.SCol_1}][{Data.SLayer_1}][{Data.ELine_1}][{Data.VoucherNo_1}]--[{Data.RES1_1}]");
-        }
-
-        /// <summary>
-        /// 二工位写任务
-        /// </summary>
-        /// <param name="task"></param>
-        /// <param name="goodsnum">货物数量</param>
-        public void WriteTask2(Task task, short goodsnum)
-        {
-            InfoLog.INFO_SRMINFO($"出库--写入堆垛机[{Entity.CODE}]2工位-开始:[{Data.TaskID_2}][{Data.SLine_2}][{Data.SCol_2}][{Data.SLayer_2}][{Data.ELine_2}][{Data.VoucherNo_2}]--[{Data.RES1_2}]");
-            Data.TaskID_2 = task.ID;
-            Data.SLine_2 = task.Line;
-            Data.SCol_2 = task.Col;
-            Data.SLayer_2 = task.Layer;
-            if (task.TYPE == TaskType.移库)
-            {
-                Data.ELine_2 = task.EndLine;
-                Data.ECol_2 = task.EndCol;
-                Data.ELayer_2 = task.EndLayer;
-            }
-            else
-            {
-                Data.ELine_2 = task.SRMSTATION.ToShort();
-                Data.ECol_2 = 0;
-                Data.ELayer_2 = 0;
-            }
-            Data.RES1_2 = goodsnum;
-            Data.VoucherNo_2++;
-            InfoLog.INFO_SRMINFO($"出库--写入堆垛机[{Entity.CODE}]2工位-结束:[{Data.TaskID_2}][{Data.SLine_2}][{Data.SCol_2}][{Data.SLayer_2}][{Data.ELine_2}][{Data.VoucherNo_2}]--[{Data.RES1_2}]");
-        }
-
-        /// <summary>
-        /// 获取任务对应的货叉
-        /// </summary>
-        /// <param name="task">任务信息</param>
-        /// <param name="index">任务在下发任务集合中的索引</param>
-        /// <returns></returns>
-        public SrmFork GetFork(Task task, int index)
-        {
-            return index switch
-            {
-                > 1 => throw new WarnException("一次最多下发两个任务"),
-                //如果索引是1,直接返回货叉2
-                1 => SrmFork.货叉2,
-                _ => task.Col switch
-                {
-                    102 => Entity.CODE switch
-                    {
-                        "SRM1" => SrmFork.货叉1,
-                        _ => SrmFork.货叉2,
-                    },
-                    112 => SrmFork.货叉2,
-                    _ => SrmFork.货叉1,
-                }
-            };
-        }
-
-        /// <summary>
-        /// 检查同组堆垛机是否有出库任务正在执行
-        /// </summary>
-        public void CheckOutTask()
-        {
-            //检查同组堆垛机是否有正在执行出库任务的
-            DB.Do(db =>
-            {
-                try
-                {
-                    var srm = Device.Find("SRM4").Create<SRMDevice>();
-                    var task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM4" && v.TYPE == TaskType.出库);
-                    switch (Entity.CODE)
-                    {
-                        case "SRM3":
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
-                                throw new DoException("SRM4正在执行出库任务");
-                            break;
-
-                        case "SRM4":
-                            srm = Device.Find("SRM3").Create<SRMDevice>();
-                            task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM3" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
-                                throw new DoException("SRM3正在执行出库任务");
-                            break;
-
-                        case "SRM5":
-                            srm = Device.Find("SRM6").Create<SRMDevice>();
-                            task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM6" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
-                                throw new DoException("SRM6正在执行出库任务");
-                            break;
-
-                        case "SRM6":
-                            srm = Device.Find("SRM5").Create<SRMDevice>();
-                            task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM5" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
-                                throw new DoException("SRM5正在执行出库任务");
-                            break;
-
-                        case "SRM7":
-                            srm = Device.Find("SRM8").Create<SRMDevice>();
-                            task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM8" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
-                                throw new DoException("SRM8正在执行出库任务");
-                            break;
-
-                        case "SRM8":
-                            srm = Device.Find("SRM7").Create<SRMDevice>();
-                            task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM7" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
-                                throw new DoException("SRM7正在执行出库任务");
-                            break;
-                    }
-                }
-                catch (Exception e)
-                {
-                    InfoLog.INFO_WarnDb(e.Message, Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                }
-            });
-        }
-    }
-
-    /// <summary>
-    /// 异常处理
-    /// </summary>
-    public static class DevEX
-    {
-        /// <summary>
-        /// 计算两点距离
-        /// </summary>
-        /// <param name="start">起始点</param>
-        /// <param name="end">结束点</param>
-        /// <param name="total">总长</param>
-        /// <returns></returns>
-        public static float Distance(float start, float end, float total)
-        {
-            float distance = 0;
-            if (start > end) distance = (total - start) + end;
-            else distance = end - start;
-            return distance;
-        }
-
-        public static void DoExceptionEX(this DoException ex, WCS_DEVICE Entity)
-        {
-            InfoLog.INFO_INFO($"[{Entity.CODE}]--{ex.Message}");
-        }
-
-        /// <summary>
-        /// 警报执行记录
-        /// </summary>
-        /// <param name="ex">警报信息</param>
-        /// <param name="Entity">发生设备</param>
-        /// <param name="reportMonitor">是否上报监控</param>
-        /// <exception cref="Exception"></exception>
-        public static void WarnExceptionEX(this WarnException ex, WCS_DEVICE Entity, bool reportMonitor = true)
-        {
-            InfoLog.INFO_WARN($"[{Entity.CODE}]--{ex.Message}");
-            if (ex.Message.Contains("The database operation was expected")) return;
-
-            if (!reportMonitor)
-            {
-                LogHelper.AddWCS_EXCEPTION(ex.Message, Entity.CODE, WCS_EXCEPTIONTYPE.无.ToString());
-            }
-            //排除部分频繁触发的异常上报
-            if (ex.Message.Contains("触发并发管控")) return;
-
-            if (reportMonitor)
-            {
-                throw new Exception($"[{Entity.CODE}]--{ex.Message}");
-            }
-        }
-
-        public static void ExceptionEx(this Exception ex, WCS_DEVICE Entity)
-        {
-            InfoLog.INFO_ERROR($"[{Entity.CODE}]--{ex.Message}--{ex.StackTrace}");
-            //排除部分频繁触发的异常上报
-            if (ex.Message.Contains("Collection was modified; enumeration operation may not execute.")) return;
-            Ltc.Log(ex.GetBaseException().Message);
-        }
-    }
-
-    /// <summary>
-    /// 堆垛机货叉/工位
-    /// </summary>
-    public enum SrmFork
-    {
-        货叉1 = 0,
-        货叉2 = 1,
-    }
-
-    /// <summary>
-    /// 站台位置信息
-    /// </summary>
-    public class StationLocation
-    {
-        /// <summary>
-        /// 所有环穿站台的信息
-        /// </summary>
-        public static List<StationLocation> ALLlocations { get; set; } = new List<StationLocation>();
-
-        static StationLocation()
-        {
-            ALLlocations.AddRange(new List<StationLocation>() {
-                new StationLocation("G1",486326,"RGV3",1567770),
-                new StationLocation("G2",693631,"RGV3",1567770),
-                new StationLocation("G3",789931,"RGV3",1567770),
-                new StationLocation("G4",961595,"RGV3",1567770),
-                new StationLocation("G5",1013350,"RGV3",1567770),
-                new StationLocation("G6",1069938,"RGV3",1567770),
-                new StationLocation("G7",1126338,"RGV3",1567770),
-                new StationLocation("G8",1178355,"RGV3",1567770),
-                new StationLocation("G9",1256875,"RGV3",1567770),
-                new StationLocation("G10",1313239,"RGV3",1567770),
-                new StationLocation("G11",1369970,"RGV3",1567770),
-                new StationLocation("G12",636770,"RGV1",3719290),
-                new StationLocation("G13",749520,"RGV1",3719290),
-                new StationLocation("G14",879930,"RGV1",3719290),
-                new StationLocation("G15",936310,"RGV1",3719290),
-                new StationLocation("G16",988000,"RGV1",3719290),
-                //new StationLocation("G17",1607000,"RGV1",3719290),
-                //new StationLocation("G18",1667000,"RGV1",3719290),
-                new StationLocation("G19",1785000,"RGV1",3719290),
-                //new StationLocation("G20",2548012,"RGV1",3719290),
-                //new StationLocation("G21",2606033,"RGV1",3719290),
-                //new StationLocation("G22",2660833,"RGV1",3719290),
-                new StationLocation("G23",2714350,"RGV1",3719290),
-            });
-        }
-
-        public StationLocation(string station, int location, string plc, int length)
-        {
-            Station = station;
-            Location = location;
-            PLC = plc;
-            Length = length;
-        }
-
-        /// <summary>
-        /// 输送机设备组编号
-        /// </summary>
-        public string Station { get; set; }
-
-        /// <summary>
-        /// 输送机在环轨中的位置
-        /// </summary>
-        public int Location { get; set; }
-
-        /// <summary>
-        /// 所属RGV组 PLC名称
-        /// </summary>
-        public string PLC { get; set; }
-
-        /// <summary>
-        /// 所属环穿轨道的长度
-        /// </summary>
-        public int Length { get; set; }
-    }
-
-    /// <summary>
-    /// 巷道信息
-    /// </summary>
-    public class TunnelInfo
-    {
-        public WCS_DEVICE Tunnel;
-        public WCS_DEVICE taskIN;
-        public Device<ISRM520, ISRM521, ISRM537> SRM;
-    }
-}

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

@@ -1,213 +0,0 @@
-using DBHelper;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Extensions
-{
-    /// <summary>
-    /// 任务扩展
-    /// </summary>
-    public static class TaskExtension
-    {
-        public static T Create<T>(this WCS_TASK source)
-        {
-            return (T)Activator.CreateInstance(typeof(T), source);
-        }
-
-        /// <summary>
-        /// 获取可用的出库任务
-        /// </summary>
-        /// <param name="tasks"></param>
-        /// <returns></returns>
-        public static Task[] GetOutTask(this List<WCS_TASK> tasks)
-        {
-            var tasklist = tasks.Select(v => v.Create<Task>());
-            var task = tasklist.FirstOrDefault() ?? throw new WarnException("无可用出库任务--GetOutTask");
-            //AGV任务ID不为零表示为车间叫料任务
-            if (task.AgvTask != 0)
-            {
-                //按照AGV任务ID分一次组
-                tasklist = tasklist.OrderByDescending(v => v.Priority)
-                                   .ThenBy(v => v.CREATETIME)
-                                   .GroupBy(v => v.AgvTask)
-                                   .FirstOrDefault() ?? throw new WarnException("无可用叫料任务--GetOutTask");
-                //无论这个AGV任务绑定的货物相隔多远都必须要一起出出去
-                return tasklist.OrderBy(v => v.Col).ToArray();
-            }
-            return tasklist.OrderByDescending(v => v.Priority)
-                           .GroupBy(v => v.MaterialCode)
-                           .OrderBy(v => v.Key).FirstOrDefault()
-                           .OrderByDescending(v => v.Priority)
-                           .ThenBy(v => v.Line)
-                           .ThenBy(v => v.Layer)
-                           .ThenBy(v => v.Col)
-                           .Take(2)
-                           .DistinctBy(v => v.Col)
-                           .OrderBy(v => v.Col)
-                           .ToArray();
-        }
-
-        /// <summary>
-        /// 获取出库任务的站台号及下一个地址
-        /// </summary>
-        /// <param name="task">任务</param>
-        /// <param name="srmFork">货叉</param>
-        public static void GetSrmStationAndaddNext(this WCS_TASK task, SrmFork srmFork)
-        {
-            List<Device<IStation520, IStation521, IStation523>> stations = new List<Device<IStation520, IStation521, IStation523>>();
-            //取任务巷道到达目标地址的下一个地址,即任务堆垛机的站台对应的设备组
-            if (task.TYPE == TaskType.倒库)
-            {
-                stations = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER == Device.Find(task.TUNNEL).GetPath(task.DEVICEDL)))
-                                    .Select(v => v.Create<StationDeviceGroup>())
-                                    .FirstOrDefault()?.Items
-                                    .OrderByDescending(v => v.Entity.CODE)
-                                    .ToList();
-            }
-            else
-            {
-                stations = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER == Device.Find(task.TUNNEL).GetPath(task.ADDRTO.Replace("G", ""))))
-                                    .Select(v => v.Create<StationDeviceGroup>())
-                                    .FirstOrDefault()?.Items
-                                    .OrderByDescending(v => v.Entity.CODE)
-                                    .ToList();
-            }
-            var ts = stations.ToArray();
-
-            var addNext = task.TYPE == TaskType.倒库 ? task.DEVICEDL : task.ADDRTO;
-            //一工位放较大的站台号
-            switch (srmFork)
-            {
-                case SrmFork.货叉1:
-                    task.SRMSTATION = ts?[0].Entity.CODE;
-                    task.ADDRNEXT = ts?[0].Entity.GetPath(addNext).CODE;
-                    break;
-
-                case SrmFork.货叉2:
-                    task.SRMSTATION = ts?[1].Entity.CODE;
-                    task.ADDRNEXT = ts?[1].Entity.GetPath(addNext).CODE;
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// 有效任务数是否符合任务组任务数
-        /// </summary>
-        /// <param name="tasks"></param>
-        /// <param name="executable"></param>
-        /// <param name="db"></param>
-        public static void ValidTaskCheck(this List<WCS_TASK> tasks, int executable, DB db)
-        {
-            var task = tasks.FirstOrDefault();
-            var taskCount = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey && (v.TYPE == TaskType.入库 || v.TYPE == TaskType.倒库));
-            //开始检查任务数是否匹配
-            if (executable != taskCount) throw new WarnException($"可执行数{executable},任务组任务数{taskCount},数量不匹配,{task.ID}-{task.TaskGroupKey}");
-        }
-
-        /// <summary>
-        /// 有效任务数是否符合任务组任务数  临时
-        /// </summary>
-        /// <param name="tasks"></param>
-        /// <param name="executable"></param>
-        /// <param name="db"></param>
-        public static List<WCS_TASK> ValidTaskCheck(this List<FinishTaskList<string>> devs, DB db)
-        {
-            var taskIds = devs.Select(v => v.Station.Data2.Tasknum).ToList();
-            var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-            var task = taskList.FirstOrDefault() ?? throw new WarnException($"ValidTaskCheck 无任务"); ;
-            var taskCount = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey && v.TYPE == TaskType.入库);
-            //开始检查任务数是否匹配
-            if (devs.Count != taskCount) throw new WarnException($"可执行数{devs.Count},任务组任务数{taskCount},数量不匹配,{task.ID}-{task.TaskGroupKey}");
-            return taskList;
-        }
-
-        /// <summary>
-        /// 用于任务创建时获取放货站台
-        /// </summary>
-        /// <param name="task"></param>
-        public static void TaskGetSrmStation(this WCS_TASK task)
-        {
-            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;
-        }
-
-        public static void AGVStatusChange(this WCS_AGVTask task, AGVTaskStatus status, string type = "同步")
-        {
-            var time = task.UpdateTime - task.AGVUpdateTime;
-            InfoLog.INFO_AGV($"WCS更新Status:{task.Status},AGVStatus:{status},{type};耗时:{time.Value.TotalMilliseconds};【{task.ID}】【{task.TaskType}】WCS更新时间【{task.UpdateTime}】AGV时间【{task.AGVUpdateTime}】");
-        }
-    }
-
-    public enum SrmIndex
-    {
-        工位一 = 0,
-        工位二 = 1,
-    }
-
-    public class Task : WCS_TASK
-    {
-        /// <summary>
-        /// 行
-        /// </summary>
-        public short Line { get; set; }
-
-        /// <summary>
-        /// 列
-        /// </summary>
-        public short Col { get; set; }
-
-        /// <summary>
-        /// 层
-        /// </summary>
-        public short Layer { get; set; }
-
-        /// <summary>
-        /// 行
-        /// </summary>
-        public short EndLine { get; set; }
-
-        /// <summary>
-        /// 列
-        /// </summary>
-        public short EndCol { get; set; }
-
-        /// <summary>
-        /// 层
-        /// </summary>
-        public short EndLayer { get; set; }
-
-        public Task(WCS_TASK task)
-        {
-
-            var addrFrom = task.ADDRFROM.Split("-");
-
-            ADDRTO = task.ADDRTO;
-            TUNNEL = task.TUNNEL;
-            DEVICE = task.DEVICE;
-            Priority = task.Priority;
-            AgvTask = task.AgvTask;
-            CREATETIME = task.CREATETIME;
-            MaterialCode = task.MaterialCode;
-            SRMSTATION = task.SRMSTATION;
-            ID = task.ID;
-            Line = addrFrom[0].ToShort();
-            Col = addrFrom[1].ToShort();
-            Layer = addrFrom[2].ToShort();
-            TYPE = task.TYPE;
-            if (task.TYPE == TaskType.移库)
-            {
-                var addrto = task.ADDRTO.Split("-");
-                EndLine = addrto[0].ToShort();
-                EndCol = addrto[1].ToShort();
-                EndLayer = addrto[2].ToShort();
-            }
-        }
-    }
-}

+ 32 - 35
Projects/永冠OPP/WCS.Service/Handlers/DataClearHandler.cs

@@ -1,9 +1,6 @@
-using DBHelper;
-using Microsoft.EntityFrameworkCore;
-using System;
+using System;
 using System.ComponentModel;
 using WCS.Core;
-using WCS.Entity;
 
 namespace WCS.Service
 {
@@ -18,37 +15,37 @@ namespace WCS.Service
 
         public override void Update(double milliseconds)
         {
-            if ((DateTime.Now - last).TotalMilliseconds < 1000 * 60 * 60 * 24)
-                return;
-            last = DateTime.Now;
-            DB.Do(db =>
-            {
-                db.Default.Database.ExecuteSqlRaw("delete WCS_EXCEPTION where datediff(dd,UPDATETIME,getdate())>7");
-                db.Default.Database.ExecuteSqlRaw("delete WCS_StatusLog where datediff(dd,UPDATETIME,getdate())>15");
-                var ps = db.Default.GetType().GetProperties();
-                foreach (var p in ps)
-                {
-                    if (!p.PropertyType.IsGenericType)
-                        continue;
-                    var tType = p.PropertyType.GenericTypeArguments[0];
-                    if (!tType.IsSubclassOf(typeof(WCS_PROTOCOLDATA)))
-                        continue;
-                    var sSql = $"Delete {tType.Name} where datediff(dd,Frame,getdate())>7";
-                    db.Default.Database.ExecuteSqlRaw(sSql);
-                    DBHelper.DbLog.DB_CLEAN(sSql);
-                }
+            //if ((DateTime.Now - last).TotalMilliseconds < 1000 * 60 * 60 * 24)
+            //    return;
+            //last = DateTime.Now;
+            //DB.Do(db =>
+            //{
+            //    db.Default.Database.ExecuteSqlRaw("delete WCS_EXCEPTION where datediff(dd,UPDATETIME,getdate())>7");
+            //    db.Default.Database.ExecuteSqlRaw("delete WCS_StatusLog where datediff(dd,UPDATETIME,getdate())>15");
+            //    var ps = db.Default.GetType().GetProperties();
+            //    foreach (var p in ps)
+            //    {
+            //        if (!p.PropertyType.IsGenericType)
+            //            continue;
+            //        var tType = p.PropertyType.GenericTypeArguments[0];
+            //        if (!tType.IsSubclassOf(typeof(WCS_PROTOCOLDATA)))
+            //            continue;
+            //        var sSql = $"Delete {tType.Name} where datediff(dd,Frame,getdate())>7";
+            //        db.Default.Database.ExecuteSqlRaw(sSql);
+            //        DBHelper.DbLog.DB_CLEAN(sSql);
+            //    }
 
-                var copySql = @"INSERT INTO WCS_TASK_OLD (ID,BARCODE,TYPE,STATUS,ADDRFROM,ADDRTO,ADDRNEXT,TUNNEL,FLOOR,
-                                DEVICE,SRMSTATION,CREATETIME,STARTTIME,ENDTIME,DOCID,PALLETTYPE,PRODLINE,FULLQTY,HEIGHT,
-                                WMSTASK,TaskGroupKey,UPLOADED,AgvTask,Priority,ManualRemarks,ENABLED,UPDATEUSER,UPDATETIME,
-                                Length,MaterialCode) SELECT
-                                ID,BARCODE,TYPE,STATUS,ADDRFROM,ADDRTO,ADDRNEXT,TUNNEL,FLOOR,DEVICE,SRMSTATION,CREATETIME,
-                                STARTTIME,ENDTIME,DOCID,PALLETTYPE,PRODLINE,FULLQTY,HEIGHT,WMSTASK,TaskGroupKey,UPLOADED,AgvTask,
-                                Priority,ManualRemarks,ENABLED,UPDATEUSER,UPDATETIME,Length,MaterialCode FROM WCS_TASK WHERE STATUS >=99 AND UPDATETIME < DATEADD(DAY, -3, GETDATE())";
-                db.Default.Database.ExecuteSqlRaw(copySql);
-                var clearSql = "DELETE FROM WCS_TASK WHERE STATUS >=99 AND UPDATETIME < DATEADD(DAY, -3, GETDATE())";
-                db.Default.Database.ExecuteSqlRaw(clearSql);
-            });
+            //    var copySql = @"INSERT INTO WCS_TASK_OLD (ID,BARCODE,TYPE,STATUS,ADDRFROM,ADDRTO,ADDRNEXT,TUNNEL,FLOOR,
+            //                    DEVICE,SRMSTATION,CREATETIME,STARTTIME,ENDTIME,DOCID,PALLETTYPE,PRODLINE,FULLQTY,HEIGHT,
+            //                    WMSTASK,TaskGroupKey,UPLOADED,AgvTask,Priority,ManualRemarks,ENABLED,UPDATEUSER,UPDATETIME,
+            //                    Length,MaterialCode) SELECT
+            //                    ID,BARCODE,TYPE,STATUS,ADDRFROM,ADDRTO,ADDRNEXT,TUNNEL,FLOOR,DEVICE,SRMSTATION,CREATETIME,
+            //                    STARTTIME,ENDTIME,DOCID,PALLETTYPE,PRODLINE,FULLQTY,HEIGHT,WMSTASK,TaskGroupKey,UPLOADED,AgvTask,
+            //                    Priority,ManualRemarks,ENABLED,UPDATEUSER,UPDATETIME,Length,MaterialCode FROM WCS_TASK WHERE STATUS >=99 AND UPDATETIME < DATEADD(DAY, -3, GETDATE())";
+            //    db.Default.Database.ExecuteSqlRaw(copySql);
+            //    var clearSql = "DELETE FROM WCS_TASK WHERE STATUS >=99 AND UPDATETIME < DATEADD(DAY, -3, GETDATE())";
+            //    db.Default.Database.ExecuteSqlRaw(clearSql);
+            //});
         }
     }
-}
+}

+ 7 - 7
Projects/永冠OPP/WCS.Service/Handlers/UploadHandler.cs

@@ -20,13 +20,13 @@ namespace WCS.Service
         DateTime last = DateTime.MinValue;
         public override void Update(double milliseconds)
         {
-            if ((DateTime.Now - last).TotalMilliseconds < 10000)
-                return;
-            last = DateTime.Now;
-            DB.Do(db => 
-            {
-                Uploader.Upload(db);
-            }); 
+            //if ((DateTime.Now - last).TotalMilliseconds < 10000)
+            //    return;
+            //last = DateTime.Now;
+            //DB.Do(db => 
+            //{
+            //    Uploader.Upload(db);
+            //}); 
         }
     }
 }

+ 0 - 61
Projects/永冠OPP/WCS.Service/Helpers/DeciceStateHelper.cs

@@ -1,61 +0,0 @@
-using DBHelper;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Entity.Protocol;
-
-namespace WCS.Service.Helpers
-{
-    /// <summary>
-    /// 状态管理中心
-    /// </summary>
-    public class DeciceStateHelper
-    {
-        /// <summary>
-        /// 状态记录
-        /// </summary>
-        public static Dictionary<string, string> StateLog = new Dictionary<string, string>();
-
-        /// <summary>
-        /// 状态检查
-        /// </summary>
-        public static void StatusCheck(string devCode, string state)
-        {
-            if (StateLog.Any(v => v.Key == devCode))
-            {
-                if (StateLog.Any(v => v.Key == devCode && v.Value != state))
-                {
-                    DB.Do(db =>
-                    {
-                        WCS_DEVICESTATELOG dev = new WCS_DEVICESTATELOG()
-                        {
-                            DEVICECODE = devCode,
-                            STATE = state,
-                            UPDATETIME = DateTime.Now,
-                            UPDATEUSER = "WCS"
-                        };
-                        db.Default.Add(dev);
-                        db.Default.SaveChanges();
-                    });
-                    StateLog[devCode] = state;
-                }
-            }
-            else //初始化
-            {
-                StateLog.Add(devCode, state);
-                DB.Do(db =>
-                {
-                    WCS_DEVICESTATELOG dev = new WCS_DEVICESTATELOG()
-                    {
-                        DEVICECODE = devCode,
-                        STATE = state,
-                        UPDATETIME = DateTime.Now,
-                        UPDATEUSER = "WCS"
-                    };
-                    db.Default.Add(dev);
-                    db.Default.SaveChanges();
-                });
-            }
-        }
-    }
-}

+ 0 - 94
Projects/永冠OPP/WCS.Service/Helpers/DeviceTaskTimeHelper.cs

@@ -1,94 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Entity.Protocol;
-using WCS.Service.Extensions;
-using WCS.Service.Log;
-
-namespace WCS.Service.Helpers
-{
-    /// <summary>
-    /// 设备任务时长统计
-    /// </summary>
-    public static class DeviceTaskTimeHelper
-    {
-        public static List<DeviceTaskTimeViewModel> deviceTaskTimes = new List<DeviceTaskTimeViewModel>();
-
-        /// <summary>
-        /// 添加AGV开始记录
-        /// </summary>
-        public static void Add(this RGVDevice rgv)
-        {
-            if (deviceTaskTimes.Any(v => v.DeviceCode == rgv.Entity.CODE)) return;
-
-            deviceTaskTimes.Add(new DeviceTaskTimeViewModel
-            {
-                DeviceCode = rgv.Entity.CODE,
-                StartTime = DateTime.Now,
-                TaskType = rgv.Data.TaskType_1.ToString(),
-                StartAdd = rgv.CurrentStation().Entity.CODE,
-                EndAdd = rgv.Data.DestPosition_1.ToString(),
-            });
-        }
-
-        /// <summary>
-        /// 添加AGV开始记录
-        /// </summary>
-        public static void End(this RGVDevice rgv)
-        {
-            if (deviceTaskTimes.Any(v => v.DeviceCode == rgv.Entity.CODE && v.TaskType == rgv.Data2.TaskType_1.ToString()))
-            {
-                var deviceTaskTime = deviceTaskTimes.Find(v => v.DeviceCode == rgv.Entity.CODE);
-                deviceTaskTime.EndTime = DateTime.Now;
-                deviceTaskTime.SumTime = (deviceTaskTime.EndTime - deviceTaskTime.StartTime).TotalSeconds;
-                InfoLog.INFO_DEVICETASKTIME(JsonConvert.SerializeObject(deviceTaskTime));
-                deviceTaskTimes.Remove(deviceTaskTime);
-            }
-        }
-    }
-
-    /// <summary>
-    ///
-    /// </summary>
-    public class DeviceTaskTimeViewModel
-    {
-        /// <summary>
-        /// 设备号
-        /// </summary>
-        public string DeviceCode { get; set; }
-
-        /// <summary>
-        /// 开始时间
-        /// </summary>
-
-        public DateTime StartTime { get; set; }
-
-        /// <summary>
-        /// 结束时间
-        /// </summary>
-
-        public DateTime EndTime { get; set; }
-
-        /// <summary>
-        /// 总计时间
-        /// </summary>
-
-        public double SumTime { get; set; }
-
-        /// <summary>
-        /// 任务类型
-        /// </summary>
-        public string TaskType { get; set; }
-
-        /// <summary>
-        /// 起始地址
-        /// </summary>
-        public string StartAdd { get; set; }
-
-        /// <summary>
-        /// 目标地址
-        /// </summary>
-        public string EndAdd { get; set; }
-    }
-}

+ 0 - 97
Projects/永冠OPP/WCS.Service/Helpers/FinishTaskList.cs

@@ -1,97 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Service.Entity;
-using WCS.Service.Extensions;
-using WCS.Service.Log;
-
-namespace WCS.Service.Helpers
-{
-    /// <summary>
-    /// 处理完成任务记录集合
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class FinishTaskList<T>
-    {
-        public FinishTaskList(T finishCode, StationDevice station)
-        {
-            FinishCode = finishCode;
-            Station = station;
-        }
-
-        /// <summary>
-        /// 完成
-        /// </summary>
-        public T FinishCode { get; set; }
-
-        /// <summary>
-        /// 对应设备信息
-        /// </summary>
-        public StationDevice Station { get; set; }
-    }
-
-    /// <summary>
-    /// 处理完成任务记录集合
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class FinishTaskList<T, T1>
-    {
-        public FinishTaskList(T finishCode, T1 station)
-        {
-            FinishCode = finishCode;
-            Station = station;
-        }
-
-        /// <summary>
-        /// 完成
-        /// </summary>
-        public T FinishCode { get; set; }
-
-        /// <summary>
-        /// 对应设备信息
-        /// </summary>
-        public T1 Station { get; set; }
-    }
-
-    public static class FinishTaskListExtensions
-    {
-        /// <summary>
-        /// 入库可用任务数是否有效
-        /// </summary>
-        /// <param name="finishes"></param>
-        /// <exception cref="WarnException"></exception>
-        public static bool Valid(this List<FinishTaskList<string>> finishes, string code)
-        {
-            var res = true;
-            var maxGoodsnum = finishes.Select(v => v.Station.Data2.Goodsnum).OrderByDescending(v => v).FirstOrDefault();
-            if (finishes.Count != maxGoodsnum)
-            {
-                InfoLog.INFO_WarnDb($"可用货物数{finishes.Count},实际货物数{maxGoodsnum}", code, WCS.Entity.WCS_EXCEPTIONTYPE.逻辑异常);
-                res = false;
-            };
-            if (!finishes.Any())
-            {
-                InfoLog.INFO_WarnDb("没有任务", code, WCS.Entity.WCS_EXCEPTIONTYPE.逻辑异常);
-                res = false;
-            }
-            return res;
-        }
-
-        /// <summary>
-        /// 入库可用任务数是否有效
-        /// </summary>
-        /// <param name="finishes"></param>
-        /// <exception cref="WarnException"></exception>
-        public static List<I_WCS_GetInTaskResponseItem> GetWMSInTask(this List<FinishTaskList<string>> finishes)
-        {
-            if (!finishes.Any()) throw new DoException("没有任务");
-            var items = finishes.ToArray();
-            var infos = items.Length switch
-            {
-                1 => WMS.I_WCS_GetInTask(items[0].FinishCode, items[0].Station.Entity.CODE),
-                2 => WMS.I_WCS_GetInTask(items[0].FinishCode, items[0].Station.Entity.CODE, items[1].FinishCode, items[1].Station.Entity.CODE),
-                _ => throw new WarnException($"一组任务数量最大为2,当前{items.Length}"),
-            };
-            return infos;
-        }
-    }
-}

+ 10 - 15
Projects/永冠OPP/WCS.Service/ProtocolProxy.cs

@@ -2,7 +2,6 @@
 using FreeRedis;
 using MessagePack;
 using MessagePack.Resolvers;
-using Microsoft.CodeAnalysis.Differencing;
 using Microsoft.EntityFrameworkCore;
 using System;
 using System.Collections.Concurrent;
@@ -60,10 +59,10 @@ namespace WCS.Service
                 for (int i = 0; i < list.Count - 1; i++)
                 {
                     var obj = list[i];
-                    db.Default.Attach(obj);
+                    //db.Default.Attach(obj);
                     obj.ISLAST = false;
                 }
-                db.Default.SaveChanges();
+                //db.Default.SaveChanges();
             }
             var res = Enumerable.LastOrDefault(list);
             return res;
@@ -77,19 +76,19 @@ namespace WCS.Service
 
             if (last != null)
             {
-                db.Default.Attach(last);
+                //db.Default.Attach(last);
                 last.ISLAST = false;
             }
 
-            db.Default.Attach(PROTOCOL.DEVICE);
+            //db.Default.Attach(PROTOCOL.DEVICE);
 
             newobj.DEVICE = PROTOCOL.DEVICE;
             newobj.ISLAST = true;
             newobj.UPDATETIME = DateTime.Now;
             newobj.UPDATEUSER = user;
             newobj.FRAME = LogicHandler.Frame;
-            db.Default.Add(newobj);
-            db.Default.SaveChanges();
+            //db.Default.Add(newobj);
+            //db.Default.SaveChanges();
             return newobj;
         }
 
@@ -97,8 +96,9 @@ namespace WCS.Service
         private static Dictionary<string, Playerback> Clients = new Dictionary<string, Playerback>();
 
         private static RedisClient Redis;
-        public static RedisClient YG150Redis;
-        public static RedisClient YGWMS150Redis;
+
+        //public static RedisClient YG150Redis;
+        //public static RedisClient YGWMS150Redis;
         public static RedisClient YGWCS150Redis;
 
         static ProtocolProxy()
@@ -117,8 +117,6 @@ namespace WCS.Service
                 return obj;
             };
 
-            YG150Redis = new RedisClient("192.168.249.150,password=123456,database=1");
-            YGWMS150Redis = new RedisClient("192.168.249.150,password=123456,database=0");
             YGWCS150Redis = new RedisClient("192.168.249.150,password=123456,database=10");
             YGWCS150Redis.Serialize = obj =>
             {
@@ -132,7 +130,6 @@ namespace WCS.Service
             };
         }
 
-        //static ConcurrentDictionary<string, DeviceData> Datas = new ConcurrentDictionary<string, DeviceData>();
         public override void Publish(string code, WCS_PROTOCOLDATA obj)
         {
             try
@@ -232,7 +229,6 @@ namespace WCS.Service
                     Redis.LTrim("Packs", 20000, len);
                 }
 
-
                 var len1 = YGWCS150Redis.LLen("Packs");
                 if (len1 > 150000)
                 {
@@ -255,7 +251,6 @@ namespace WCS.Service
             catch (Exception ex)
             {
             }
-            //Datas.Clear();
         }
     }
 
@@ -265,4 +260,4 @@ namespace WCS.Service
 
         public byte[] Data { get; set; }
     }
-}
+}

+ 3 - 0
Projects/永冠OPP/WCS.Service/WCS.Service.csproj → Projects/永冠OPP/WCS.Service/WCS.DataCollectionService.csproj

@@ -50,5 +50,8 @@
 
   <ItemGroup>
     <Folder Include="Log\" />
+    <Folder Include="Works\RGV\" />
+    <Folder Include="Works\SRM\" />
+    <Folder Include="Works\Station\" />
   </ItemGroup>
 </Project>

+ 2 - 18
Projects/永冠OPP/WCS.Service/Worker.cs

@@ -43,7 +43,6 @@ namespace WCS.Service
 
             Configs.PublishEvent += () =>
             {
-                WMS.UploadDevInfo();
                 ProtocolProxy.Do();
             };
             Configs.UploadException = (d, s) =>
@@ -58,20 +57,7 @@ namespace WCS.Service
                 WMS.TaskException(d, s);
             };
 
-            LogicHandler.DbLog = (msg, device, type) => Helpers.LogHelper.AddWCS_EXCEPTION(msg, device, type);
-
-            //Configs.DoCmds = act =>
-            //{
-            //    DB.Do(db =>
-            //    {
-            //        var cmds = db.Default.Set<WCS_CMD>().Where(v => v.ENABLED).ToArray();
-            //        Parallel.ForEach(cmds, cmd =>
-            //        {
-            //            act(cmd);
-            //            cmd.ENABLED = false;
-            //        });
-            //    });
-            //};
+            //LogicHandler.DbLog = (msg, device, type) => Helpers.LogHelper.AddWCS_EXCEPTION(msg, device, type);
 
             PLCAccessor.Creater = new PLCAccessors.PLCAccessorsCreater();
             try
@@ -79,14 +65,12 @@ namespace WCS.Service
                 DB.Do(db =>
                 {
                     var items = db.Default.Set<WCS_DEVICEPROTOCOL>()
-                   //.Where(v => v.ENABLED && v.DEVICE.ENABLED && v.DB.ENABLED && v.DB.PLC.ENABLED)
                    .Include(v => v.DEVICE.ROUTES)
                    .Include(v => v.DEVICE.PATHS)
                    .Include(v => v.DB.PLC).ToArray();
                     items.Select(v => v.Data()).ToArray();
                     LogicHandler.AllObjects.AddRange(items);
 
-                    //var devices = items.GroupBy(v => v.DEVICE).Select(v => v.Key).ToArray();
                     var devices = db.Default.Set<WCS_DEVICE>().Include(v => v.ROUTES).Include(v => v.PATHS).Include(v => v.DEVICEGROUP).ToArray();
                     LogicHandler.AllObjects.AddRange(devices);
                 });
@@ -152,4 +136,4 @@ namespace WCS.Service
             return base.StopAsync(cancellationToken);
         }
     }
-}
+}

+ 0 - 420
Projects/永冠OPP/WCS.Service/Works/RGV/RGVWorks.cs

@@ -1,420 +0,0 @@
-using DBHelper;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol.RGV;
-using WCS.Service.Extensions;
-using WCS.Service.Handlers;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Works.RGV
-{
-    [WorkTitle(typeof(RGVHandler), "直穿RGV")]
-    public class 直穿RGV : DeviceWork<RGVDevice>
-    {
-        private readonly string ConvGroup_1030 = "G1030";
-        private readonly string RGV8 = "RGV8";
-
-        protected override void Do(RGVDevice rgv)
-        {
-            rgv.EX(rgv =>
-            {
-                //RGV是自动且空闲的
-                if (rgv.Data2.WorkMode != RGVMode.自动) throw new DoException($"{rgv.Data2.WorkMode}");
-                if (rgv.Data2.SystemStatus != RGVRunStatus.空闲) throw new DoException($"{rgv.Data2.SystemStatus}");
-                if (rgv.Data.Trigger_1 != rgv.Data2.Trigger_1) throw new WarnException("凭证好不一致");
-                if (rgv.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new DoException("RGV有光电,无法执行任务");
-
-                //RGV状态为 RGV到站&&任务完成 时程序认为RGV当前不在取货点
-                if (rgv.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站) && rgv.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.任务完成))
-                {
-                    //下达一个目标为1030的移动任务
-                    rgv.Data.TaskID_1 = 1030;
-                    rgv.Data.DestPosition_1 = 1030;
-                    rgv.Data.TaskType_1 = RGVTaskType.移动;
-                    rgv.Data.Trigger_1++;
-                }
-
-                var obj = Device.Find(ConvGroup_1030).Create<StationDeviceGroup>();
-
-                obj.WhetherToExecute();
-
-                //筛选出有任务号和起始及目标地址的设备
-                var dev = obj.RGVGetTaskedDevice() ?? throw new WarnException("无可用任务");
-                var taskids = dev.Select(v => v.Data2.Tasknum);
-                DB.Do(db =>
-                {
-                    var tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID));
-                    if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
-                        throw new WarnException("任务组ID不一致");
-                    if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
-                        throw new WarnException("无任务组ID");
-                    var gw1 = obj.Items.ToArray()[0];
-                    var gw2 = obj.Items.ToArray()[1];
-                    if (gw1.Data2.Tasknum != 0 && gw2.Data2.Tasknum != 0)
-                    {
-                        if (gw1.Data2.Goodsend != gw2.Data2.Goodsend) throw new WarnException($"{obj.Entity.CODE}目标地址不一致");
-                    }
-
-                    rgv.Data.TaskID_1 = gw1.Data2.Tasknum;
-                    rgv.Data.TaskID_2 = gw2.Data2.Tasknum;
-                    if (gw1.Data2.Tasknum != 0)
-                    {
-                        rgv.Data.StartPosition_1 = gw1.Entity.CODE.ToShort();
-                        rgv.Data.DestPosition_1 = gw1.Data2.Goodsend;
-                    }
-                    else
-                    {
-                        rgv.Data.StartPosition_1 = gw1.Entity.CODE.ToShort();
-                        rgv.Data.DestPosition_1 = gw2.Data2.Goodsend;
-                    }
-                    rgv.Data.Trigger_1++;
-
-                    foreach (var task in tasks)
-                    {
-                        task.CreateStatusLog(db, "RGV开始执行", this.GetType());
-                    }
-                    db.Default.SaveChanges();
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == RGV8;
-        }
-    }
-
-    [WorkTitle(typeof(RGVHandler), "涂布环穿")]
-    public class 涂布环穿 : DeviceWork<RGVDevice>
-    {
-        protected override void Do(RGVDevice obj)
-        {
-            //11号站台是取货点,但不是待命点,如需取货,从九号站台调车
-            //2号站台是一个待命点,但是为了保证入库取货效率,所有后面会跟一个车
-            //如果3号站台的小车拦住了后一个小车的放货任务,检测一次最近的空车距离值,如果大于或等于618500并且小于被拦住小车的位置值再进行调车,用于避免无效空跑
-            obj.EX(rgvDevice =>
-            {
-                //状态上抛
-                DeciceStateHelper.StatusCheck(obj.Entity.CODE, obj.Data2.WorkMode.ToString());
-                if (rgvDevice.Data2.Trigger_1 != rgvDevice.Data.Trigger_1) throw new WarnException($"等待执行任务{rgvDevice.Data2.TaskID_1}--{rgvDevice.Data2.TaskID_2}");
-                if (rgvDevice.Data2.WorkMode != RGVMode.自动) throw new DoException(rgvDevice.Data2.WorkMode.ToString());
-                if (rgvDevice.Data2.SystemStatus != RGVRunStatus.空闲) throw new DoException(rgvDevice.Data2.SystemStatus.ToString());
-                rgvDevice.End();
-                //RGV当前是否刚刚完成取货任务,等待放货
-                if (rgvDevice.IsPut())
-                {
-                    if (!rgvDevice.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV无光电,无法放货,请检查实际情况");
-                    var taskids = new List<int>() { rgvDevice.Data2.TaskID_1, rgvDevice.Data2.TaskID_2 };
-                    List<WCS_TASK> tasks = new List<WCS_TASK>();
-                    //取小车上的任务
-                    DB.Do(db =>
-                    {
-                        tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID)).ToList();
-                    });
-
-                    if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
-                        throw new WarnException("任务组ID不一致");
-                    if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
-                        throw new WarnException("无任务组ID");
-                    var destStation = Device.Find(tasks.FirstOrDefault()!.ADDRNEXT).Create<StationDeviceGroup>();
-                    rgvDevice.Put(destStation, rgvDevice.Data2.TaskID_1, rgvDevice.Data2.TaskID_2);
-                    rgvDevice.Add();
-                    return;
-                }
-                //当前有rgv的取货站台
-                var pickStation = rgvDevice.CurrentStation();
-                //RGV是否在任何一个站台
-                if (pickStation != null)
-                {
-                    //是否是取货站台
-                    if (pickStation.Entity.Is(DF.涂布RGV取货设备组))
-                    {
-                        // 筛选出有任务号和起始及目标地址的设备
-                        var devise = pickStation.RGVGetTaskedDevice();
-
-                        //是否需要取货
-                        if (devise is { Count: > 0 } && pickStation.IsPickUp(rgvDevice))
-                        {
-                            if (rgvDevice.Data.TaskID_1 != pickStation.Entity.CODE.Replace("G", "").ToShort()) throw new WarnException($"目标站台{rgvDevice.Data.TaskID_1}与当前站台{pickStation.Entity.CODE.Replace("G", "").ToShort()}不一致");
-                            if (rgvDevice.Data2.TaskType_1 != RGVTaskType.移动) throw new WarnException($"RGV正在执行{rgvDevice.Data2.TaskType_1}");
-                            if (rgvDevice.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV有光电,无法取货,请检查实际情况");
-                            if (!rgvDevice.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站)) throw new WarnException("RGV无到站状态,请检查RGV实际状态");
-                            var taskids = devise.Select(v => v.Data2.Tasknum);
-                            List<WCS_TASK> tasks = new List<WCS_TASK>();
-                            //开始下达取货任务
-                            DB.Do(db =>
-                            {
-                                tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID)).ToList();
-                            });
-                            if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
-                                throw new WarnException("任务组ID不一致");
-                            if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
-                                throw new WarnException("无任务组ID");
-                            var gw1 = pickStation.Items.ToArray()[0];
-                            var gw2 = pickStation.Items.ToArray()[1];
-                            if (gw1.Data2.Tasknum != 0 && gw2.Data2.Tasknum != 0)
-                            {
-                                if (gw1.Data2.Goodsend != gw2.Data2.Goodsend) throw new WarnException($"{rgvDevice.Entity.CODE}目标地址不一致");
-                            }
-
-                            InfoLog.INFO_RGVINFO($"[{rgvDevice.Entity.CODE}]--写入RGV取货任务-开始:{rgvDevice.Data.TaskID_1},{rgvDevice.Data.TaskID_2},{rgvDevice.Data.TaskType_1},{rgvDevice.Data.DestPosition_1},{rgvDevice.Data.Trigger_1}");
-                            rgvDevice.Data.TaskID_1 = gw1.Data2.Tasknum;
-                            rgvDevice.Data.TaskID_2 = gw2.Data2.Tasknum;
-                            rgvDevice.Data.TaskType_1 = RGVTaskType.取货;
-                            rgvDevice.Data.DestPosition_1 = pickStation.Entity.CODE.Replace("G", "").ToShort();
-                            InfoLog.INFO_RGVINFO($"[{rgvDevice.Entity.CODE}]--写入RGV取货任务-结束:{rgvDevice.Data.TaskID_1},{rgvDevice.Data.TaskID_2},{rgvDevice.Data.TaskType_1},{rgvDevice.Data.DestPosition_1},{rgvDevice.Data.Trigger_1}");
-                            rgvDevice.Data.Trigger_1++;
-                            DB.Do(db =>
-                            {
-                                foreach (var task in tasks)
-                                {
-                                    task.CreateStatusLog(db, $"取货任务下达至{rgvDevice.Entity.CODE}", this.GetType());
-                                }
-                                db.Default.SaveChanges();
-                            });
-                            rgvDevice.Add();
-                            return;
-                        }
-
-                        if (rgvDevice.RGVList.Count + 1 != 6)//有小车进入维修站时启用该逻辑,避免在正常使用时影响效率,RGVList把自身排除在外了所以需要+1
-                        {
-                            //var stationList = rgvDevice.LocationList.Where(v => v.Entity.Is(DF.涂布RGV取货设备组)).Where(v => v.RGVGetTaskedDevice().Any())
-                            //    .Where(v =>
-                            //    {
-                            //        if (v.CurrentRGV() == null) return true;
-                            //        return false;
-                            //    });
-                            //if (stationList != null)
-                            //{
-                            //    var station11 = stationList.MinBy(rgvDevice.Distance);
-                            //    //该站台到当前小车的范围中没有车
-                            //    if (rgvDevice.RGVList.Any(v => station11!.Position <= v.Position && rgvDevice.Position > v.Position))
-                            //    {
-                            //        rgvDevice.Move(station11);
-                            //        return;
-                            //    }
-                            //}
-                        }
-                        if (pickStation.Entity.CODE == "G9")
-                        {
-                            //九站台的小车需要额外检测一下11站台是否需要取货
-                            var station11 = Device.Find("G11").Create<StationDeviceGroup>();
-                            var station11Dev = station11.RGVGetTaskedDevice();
-                            if (station11Dev != null && station11Dev.Count > 0)
-                            {
-                                rgvDevice.Move(station11);
-                                rgvDevice.Add();
-                                return;
-                            }
-                        }
-
-                        //找到自己的后一个小车
-                        var afterRgv = rgvDevice.After();
-
-                        //自己是否阻挡了该小车
-                        if (afterRgv.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.SystemStatus != RGVRunStatus.空闲 && rgvDevice.StopedByMe(afterRgv))
-                        {
-                            switch (pickStation.Entity.CODE)
-                            {
-                                case "G2":
-                                    {
-                                        if (rgvDevice.RGVList.Count + 1 != 6) break;
-                                        //此站台因需要进行排队,因此是否需要赶车取决于是否拦住了两个小车的任务
-                                        var afterRgv1 = afterRgv.After();
-                                        //如果是空闲或者没有拦住他,就不执行赶车
-                                        if (afterRgv1.Data2.WorkMode == RGVMode.自动 && (afterRgv1.Data2.SystemStatus == RGVRunStatus.空闲 || !afterRgv.StopedByMe(afterRgv1))) return;
-                                        break;
-                                    }
-                                case "G3":
-                                    {
-                                        if (rgvDevice.RGVList.Count + 1 != 6) break;
-                                        //为了减少空跑,需要被阻拦的小车后面的小车任务类型为移动并且位置值要大于618500小于被阻拦小车的位置值
-                                        var afterRgv1 = afterRgv.After();
-                                        if (afterRgv1.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.TaskType_1 != RGVTaskType.移动 && !(afterRgv1.Position < afterRgv.Position && afterRgv1.Position > 618500)) return;
-                                        break;
-                                    }
-                            }
-                            //找到当前所在站台的下一个取货点
-                            var beforeStation = Device.Where(v => v.Is(DF.涂布RGV取货设备组) && v.CODE != pickStation.Entity.CODE)
-                                .Select(v => v.Create<StationDeviceGroup>()).MinBy(v => pickStation.Distance(v));
-
-                            //写入移动任务
-                            rgvDevice.Move(beforeStation);
-                            rgvDevice.Add();
-                            return;
-                        }
-
-                        if (pickStation.Entity.CODE == "G11")
-                        {
-                            rgvDevice.Move(Device.Find("G2").Create<StationDeviceGroup>());
-                            rgvDevice.Add();
-                            return;
-                        }
-                    }
-
-                    //是否在一个放货站台
-                    if (pickStation.Entity.Is(DF.涂布RGV放货设备组))
-                    {
-                        pickStation = rgvDevice.BeforeStation();
-                        rgvDevice.Move(pickStation);
-                        rgvDevice.Add();
-                        return;
-                    }
-                }
-
-                //此时RGV即没有等待执行的放货任务,也不在任何一个取货点,因此需要调往最近的一个取货点
-                //找到距离这个RGV最近的一个取货点
-                //必须所有RGV都是空闲状态时才可以进行初始化
-                if (rgvDevice.RGVList.Any(v => v.Data2.SystemStatus != RGVRunStatus.空闲)) return;
-                pickStation = rgvDevice.BeforeStation();
-                rgvDevice.Move(pickStation);
-                rgvDevice.Add();
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.Is(DF.涂布RGV);
-        }
-    }
-
-    [WorkTitle(typeof(RGVHandler), "BOPP环穿")]
-    public class BOPP环穿 : DeviceWork<RGVDevice>
-    {
-        protected override void Do(RGVDevice obj)
-        {
-            obj.EX(obj =>
-            {
-                //状态上抛
-                DeciceStateHelper.StatusCheck(obj.Entity.CODE, obj.Data2.WorkMode.ToString());
-                if (obj.Data2.Trigger_1 != obj.Data.Trigger_1) throw new WarnException($"等待执行任务{obj.Data2.TaskID_1}--{obj.Data2.TaskID_2}");
-                if (obj.Data2.WorkMode != RGVMode.自动) throw new DoException(obj.Data2.WorkMode.ToString());
-                if (obj.Data2.SystemStatus != RGVRunStatus.空闲) throw new DoException(obj.Data2.SystemStatus.ToString());
-                //RGV当前是否刚刚完成取货任务,等待放货
-                if (obj.IsPut())
-                {
-                    if (!obj.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV无光电,无法放货,请检查实际情况");
-                    //取小车上的任务
-                    DB.Do(db =>
-                    {
-                        List<int> taskids = new List<int>() { obj.Data2.TaskID_1, obj.Data2.TaskID_2 };
-                        var tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID));
-                        if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
-                            throw new WarnException("任务组ID不一致");
-                        if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
-                            throw new WarnException("无任务组ID");
-                        var destStation = Device.Find(tasks.FirstOrDefault().ADDRNEXT).Create<StationDeviceGroup>();
-                        obj.Put(destStation, obj.Data2.TaskID_1, obj.Data2.TaskID_2);
-                    });
-
-                    return;
-                }
-
-                var pickStation = obj.CurrentStation();
-                //RGV是否在任何一个站台
-                if (pickStation != null)
-                {
-                    //是否是取货站台
-                    if (pickStation.Entity.Is(DF.BOPPRGV取货设备组))
-                    {
-                        // 筛选出有任务号和起始及目标地址的设备
-                        var devs = pickStation.RGVGetTaskedDevice();
-                        //是否需要取货
-                        if (devs != null && devs.Count() > 0)
-                        {
-                            if (obj.Data2.TaskType_1 != RGVTaskType.移动) throw new WarnException($"RGV正在执行{obj.Data2.TaskType_1}");
-                            if (obj.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.光电)) throw new WarnException("RGV有光电,无法取货,请检查实际情况");
-                            if (!obj.Data2.Status_1.HasFlag(WCS.Entity.Protocol.RGVStatus.RGV到站)) throw new WarnException("RGV无到站状态,请检查RGV实际状态");
-                            var taskids = devs.Select(v => v.Data2.Tasknum);
-                            //开始下达取货任务
-                            DB.Do(db =>
-                            {
-                                var tasks = db.Default.Set<WCS_TASK>().Where(p => taskids.Contains(p.ID));
-                                if (tasks.GroupBy(p => p.TaskGroupKey).Count() > 1)
-                                    throw new WarnException("任务组ID不一致");
-                                if (!tasks.GroupBy(p => p.TaskGroupKey).Any())
-                                    throw new WarnException("无任务组ID");
-                                var gw1 = pickStation.Items.ToArray()[0];
-                                var gw2 = pickStation.Items.ToArray()[1];
-                                if (gw1.Data2.Tasknum != 0 && gw2.Data2.Tasknum != 0)
-                                {
-                                    if (gw1.Data2.Goodsend != gw2.Data2.Goodsend) throw new WarnException($"{obj.Entity.CODE}目标地址不一致");
-                                }
-                                obj.Pick(pickStation, gw1.Data2.Tasknum, gw2.Data2.Tasknum);
-
-                                foreach (var task in tasks)
-                                {
-                                    task.CreateStatusLog(db, $"取货任务下达至{obj.Entity.CODE}", this.GetType());
-                                }
-                            });
-                            return;
-                        }
-
-                        ////找到自己的后一个小车
-                        //var afterRgv = obj.After();
-
-                        ////自己是否阻挡了该小车
-                        //if (afterRgv.Data2.WorkMode == RGVMode.自动 && afterRgv.Data2.SystemStatus != RGVRunStatus.空闲 && obj.StopedByMe(afterRgv))
-                        //{
-                        //    //找到当前所在站台的下一个取货点
-                        //    var beforeStation = Device.Where(v => v.Is(DF.BOPPRGV取货设备组) && v.CODE != pickStation.Entity.CODE)
-                        //                  .Select(v => v.Create<StationDeviceGroup>())
-                        //                  .OrderBy(v => pickStation.Distance(v))
-                        //                  .FirstOrDefault();
-                        //    //写入移动任务
-                        //    obj.Move(beforeStation);
-                        //    return;
-                        //}
-                        //else
-                        //{
-                        //    //取前一个取货点
-                        //    pickStation = obj.BeforeStation();
-                        //    //前一个取货点的小车
-                        //    var rgv = pickStation.CurrentRGV();
-                        //    //前一个取货点没有车 且没有非空闲目的地为前一个取货点的小车
-                        //    if (rgv == null && !obj.RGVList.Any(v => v.Data2.SystemStatus != RGVRunStatus.空闲 && v.Data2.DestPosition_1 == pickStation.Entity.CODE.Replace("G", "").ToShort()))
-                        //    {
-                        //        obj.Move(pickStation);
-                        //        return;
-                        //    }
-                        //}
-                        //计算当前RGV拦住小车的数量
-                        var max = obj.RGVList.Count(v => v.Data2.WorkMode == RGVMode.自动 && v.Data2.SystemStatus != RGVRunStatus.空闲 && obj.StopedByMe(v));
-                        if (pickStation.Entity.CODE == "G19" && max > 2)
-                        {
-                            obj.Move(Device.Find("G23").Create<StationDeviceGroup>());
-                        }
-                        //else if (pickStation.Entity.CODE == "G23" && max > 3)
-                        //{
-                        //    obj.Move(Device.Find("G19").Create<StationDeviceGroup>());
-                        //}
-                    }
-
-                    //是否在一个放货站台
-                    if (pickStation.Entity.Is(DF.BOPPRGV放货设备组))
-                    {
-                        pickStation = obj.BeforeStation();
-                        obj.Move(Device.Find("G23").Create<StationDeviceGroup>());
-                    }
-                    return;
-                }
-
-                //此时RGV即没有等待执行的放货任务,也不在任何一个取货点,因此需要调往最近的一个取货点
-                //找到距离这个RGV最近的一个取货点
-                //必须所有RGV都是空闲状态时才可以进行初始化
-                if (obj.RGVList.Any(v => v.Data2.SystemStatus != RGVRunStatus.空闲 || v.Data2.WorkMode != RGVMode.自动)) return;
-                pickStation = obj.BeforeStation();
-                obj.Move(Device.Find("G23").Create<StationDeviceGroup>());
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.Is(DF.BOPPRGV);
-        }
-    }
-}

+ 0 - 724
Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs

@@ -1,724 +0,0 @@
-using DBHelper;
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.SRM;
-using WCS.Service.Entity;
-using WCS.Service.Extensions;
-using WCS.Service.Handlers;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Works.SRM
-{
-    [WorkTitle(typeof(SRMHandler), "堆垛机")]
-    internal class SrmWork : DeviceWork<SRMDevice>
-    {
-        protected override void Do(SRMDevice obj)
-        {
-            obj.EX(srmDevice =>
-            {
-                //状态上抛
-                DeciceStateHelper.StatusCheck(obj.Entity.CODE, obj.Data2.SRMMode.ToString());
-
-                var deviceCode = obj.Entity.CODE;
-                //先检查堆垛机是否报警
-                if (srmDevice.Data3.SCAlarm != 0)
-                {
-                    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反馈信号未清除");
-                if (srmDevice.Data2.VoucherNo_1 != srmDevice.Data.VoucherNo_1 || srmDevice.Data2.VoucherNo_2 != srmDevice.Data.VoucherNo_2)
-                {
-                    DB.Do(db =>
-                    {
-                        WCS_TASK task;
-                        if (srmDevice.Data2.VoucherNo_1 != srmDevice.Data.VoucherNo_1)
-                        {
-                            task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == srmDevice.Data.TaskID_1) ?? throw new WarnException($"未好到对应的WCS任务--{srmDevice.Data.TaskID_1}");
-                            if (task.STATUS == TaskStatus.新建)
-                            {
-                                srmDevice.Data.VoucherNo_1 = srmDevice.Data2.VoucherNo_1;
-                            }
-                        }
-                        if (srmDevice.Data2.VoucherNo_2 != srmDevice.Data.VoucherNo_2)
-                        {
-                            task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == srmDevice.Data.TaskID_2) ?? throw new WarnException($"未好到对应的WCS任务--{srmDevice.Data.TaskID_2}");
-                            if (task.STATUS == TaskStatus.新建)
-                            {
-                                srmDevice.Data.VoucherNo_2 = srmDevice.Data2.VoucherNo_2;
-                            }
-                        }
-                    });
-                    throw new WarnException($"等待执行{srmDevice.Data.TaskID_1}-{srmDevice.Data.TaskID_2}");
-                }
-
-                //处理堆垛机已完成的任务
-                if (srmDevice.Data2.FinishedTask_1 != 0 || srmDevice.Data2.FinishedTask_2 != 0)
-                {
-                    InfoLog.INFO_SRMINFO($"开始完成任务:[{deviceCode}]-{srmDevice.Data2.FinishedTask_1}-{srmDevice.Data2.FinishedTask_2}");
-                    srmDevice.FinishedTaskHandle();
-                    InfoLog.INFO_SRMINFO($"完成任务处理结束:[{deviceCode}]-{srmDevice.Data2.FinishedTask_1}-{srmDevice.Data2.FinishedTask_2}");
-                    return;
-                }
-
-                if (srmDevice.Data2.SRMMode != SCMode.远程) return;
-                if (srmDevice.Data2.SRMStatus != SCRunStatus.空闲) return;
-
-                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 == deviceCode).FirstOrDefault(v => v.STATUS == TaskStatus.堆垛机执行);
-                    if (task != null) throw new WarnException($"[{deviceCode}]有正在执行的任务:[{task.ID}]");
-                    //检测是否有未结束的倒库任务
-                    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()).Where(v => v.Is(DF.SRM涂布取货)).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>>(); //成功分配货位的任务
-                        //检测有效任务数与实际任务是是否相等
-                        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("无有效入库任务");
-                        DB.Do(db =>
-                        {
-                            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, $"堆垛机开始执行入库", 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);
-
-                                task.CreateStatusLog(db, "堆垛机开始执行出库", 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 移库
-
-                    var finishTaskList = new List<FinishTaskList<SrmFork, Task>>();
-                    DB.Do(db =>
-                    {
-                        //获取当前堆垛机未执行的任务
-                        var taskList = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == srmDevice.Entity.CODE && v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行).OrderBy(p => p.CREATETIME);
-
-                        var tasks = taskList.ToList().GetOutTask();
-                        if (tasks.Any(v => v.Layer <= 6))
-                        {
-                            if (tasks.Count(v => v.Layer <= 6) >= 2)
-                            {
-                                tasks = tasks.Take(1).ToArray();
-                            }
-                        }
-                        for (var i = 0; i < tasks.Length; 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 = WCS.Entity.TaskStatus.堆垛机执行;
-                            task.DEVICE = srmDevice.Entity.CODE;
-                            task.TaskGroupKey = tasks.Length switch
-                            {
-                                1 => $"{tasks[0].ID}_0",
-                                2 => $"{tasks[0].ID}_{tasks[1].ID}",
-                                _ => throw new WarnException($"可用任务数异常{tasks.Length}"),
-                            };
-                            var fork = srmDevice.GetFork(item, i);
-                            var msg = "";
-                            msg = fork == SrmFork.货叉1 ? $"状态由[{oldTaskStatus}]变更为[{task.STATUS}]" : $"状态由[{oldTaskStatus}]变更为[{task.STATUS}]";
-                            task.CreateStatusLog(db, msg, this.GetType());
-                            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();
-                            }
-                        }
-                    });
-
-                    #endregion 移库
-                }
-                else if (lastIsOut)
-                {
-                    #region 入库
-
-                    var floor = srmDevice.Entity.Get<int>("LastInFloor");
-                    floor = floor % 2 + 1;
-                    srmDevice.Entity.Set("LastInFloor", floor);
-                    if (enterPriority != null && outPriority != null && outPriority.Priority > enterPriority.Priority) return;
-
-                    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.Entity.Is(DF.SRM涂布取货) ? 0 : 1)
-                                       .ThenBy(v => v.Entity.Is(DF.SRMBOPP取货) ? 0 : 1)
-                                       .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>>(); //成功分配货位的任务
-                    //检测有效任务数与实际任务是是否相等
-                    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("无有效入库任务");
-                    DB.Do(db =>
-                    {
-                        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, $"堆垛机开始执行入库任务", 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()}]");
-                            }
-                        }
-                    });
-
-                    #endregion 入库
-                }
-                else
-                {
-                    #region 出库
-
-                    srmDevice.CheckOutTask();
-                    var floor = srmDevice.Entity.Get<int>("LastOutFloor");
-                    floor = floor % 2 + 1;
-                    srmDevice.Entity.Set("LastOutFloor", floor);
-                    if (enterPriority != null && outPriority != null && enterPriority.Priority > outPriority.Priority) return;
-
-                    //获取当前堆垛机所有的放货点
-
-                    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 maximum = ProtocolProxy.YGWMS150Redis.Get("SaleTaskGroupCount").ToInt();
-
-                        var cTaskList = db.Default.Set<WCS_TASK>().AsNoTracking()
-                                                                  .Where(d => d.TYPE == TaskType.出库)
-                                                                  .Where(d => d.STATUS > TaskStatus.新建)
-                                                                  .Where(d => d.STATUS < TaskStatus.已完成).ToList();
-
-                        var outDepotGrouping = waitTask.Where(v => cTaskList.Where(d => d.ADDRTO == v.ADDRTO && d.FLOOR == v.FLOOR).GroupBy(d => d.TaskGroupKey).Count() < maximum || v.ADDRTO == "G1340")
-                                                   .OrderByDescending(v => v.Priority)
-                                                   .ThenBy(v => v.ADDRTO == "G1340" ? 0 : 1)
-                                                   .ThenBy(v => v.FLOOR == floor ? 0 : 1)
-                                                   .ThenBy(v => cTaskList.Where(d => d.ADDRTO == v.ADDRTO && d.FLOOR == v.FLOOR).GroupBy(d => d.TaskGroupKey).Count())
-                                                   .ThenBy(v => v.CREATETIME)
-                                                   .GroupBy(v => v.ADDRTO)
-                                                   .FirstOrDefault();
-                        if (outDepotGrouping == null) return; //用于解决Linq  Value cannot be null. (Parameter 'source')
-
-                        var outDepotList = outDepotGrouping.Select(v => v).ToList();
-
-                        //获取两个个可执行任务,此时这两个任务的目标地址是一致的
-                        var tasks = outDepotList.GetOutTask();
-
-                        #region 校验两个产品是否为同规格
-
-                        if (tasks.Length == 2)
-                        {
-                            var length = tasks.OrderByDescending(v => v.Length).ToArray();
-                            //较大的长度减去较小的长度,差大于两百表示为不同规格产品
-                            if (length[0].Length - length[1].Length > 200)
-                            {
-                                tasks = tasks.Take(1).ToArray();
-                            }
-                        }
-
-                        #endregion 校验两个产品是否为同规格
-
-                        for (var i = 0; i < tasks.Length; 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 = WCS.Entity.TaskStatus.堆垛机执行;
-                            task.DEVICE = deviceCode;
-                            task.TaskGroupKey = tasks.Length switch
-                            {
-                                1 => $"{tasks[0].ID}_0",
-                                2 => $"{tasks[0].ID}_{tasks[1].ID}",
-                                _ => throw new WarnException($"可用任务数异常{tasks.Length}"),
-                            };
-                            var fork = srmDevice.GetFork(item, i);
-                            //获取站台及下一个地址
-                            task.GetSrmStationAndaddNext(fork);
-
-                            task.CreateStatusLog(db, "堆垛机开始执行出库任务", 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();
-                            }
-                        }
-                    });
-
-                    #endregion 出库
-                }
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.Is(DF.SRM);
-        }
-    }
-}

+ 0 - 361
Projects/永冠OPP/WCS.Service/Works/Station/BOPP入库.cs

@@ -1,361 +0,0 @@
-using DBHelper;
-using Microsoft.EntityFrameworkCore;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.SRM;
-using WCS.Service.Extensions;
-using WCS.Service.Handlers;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-using TaskStatus = WCS.Entity.TaskStatus;
-
-namespace WCS.Service.Works.Station
-{
-    /// <summary>
-    /// BOPP扫码入库
-    /// </summary>
-    [WorkTitle(typeof(BOPPHandler), "BOPP扫码入库")]
-    public class Bopp扫码入库 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                if (!stationDeviceGroup.BcrStationIsForbid()) return;
-
-                //设备组无论单卷还是双卷都必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo))
-                {
-                    InfoLog.INFO_WarnDb($"等待任务执行--凭证号不一致", obj.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                    return;
-                }
-
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位)))
-                {
-                    InfoLog.INFO_INFO($"设备运行中");
-                    return;
-                }
-
-
-                //成功创建的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                //创建对应的任务
-                DB.Do(db =>
-                {
-                    var devise = stationDeviceGroup.GetBcrValid();
-                    if (!devise.Valid(stationDeviceGroup.Entity.CODE)) return;
-                    var infos = devise.GetWMSInTask();
-
-                    foreach (var item in devise)
-                    {
-                        var dev = item.Station;
-                        var next = dev.Entity.GetPath("SRM");
-                        var info = infos.FirstOrDefault(v => item.FinishCode.Contains(v.ContainerCode + "}"));
-                        if (db.Default.Set<WCS_TASK>().AsNoTracking().Any(v => v.BARCODE == info.ContainerCode && v.STATUS < TaskStatus.已完成 && v.TYPE == TaskType.入库))
-                            throw new WarnException($"生产条码{info?.ContainerCode}存在未完成任务,请检查是否为标签卡重复使用");
-
-                        var task = new WCS_TASK
-                        {
-                            BARCODE = info?.ContainerCode,
-                            TYPE = TaskType.入库,
-                            STATUS = TaskStatus.执行中,
-                            ADDRFROM = dev.Entity.CODE,
-                            ADDRTO = info?.EndPostion,
-                            STARTTIME = DateTime.Now,
-                            UPDATEUSER = "WCS",
-                            UPDATETIME = DateTime.Now,
-                            WMSTASK = int.Parse(info?.WMSTaskNum!),
-                            TaskGroupKey = info?.TaskGroupKey,
-                            ADDRNEXT = next.CODE,
-                            HEIGHT = dev.Data2.GoodsSize,
-                            FLOOR = 2
-                        };
-
-                        db.Default.Set<WCS_TASK>().Add(task);
-                        finishTaskList.Add(new FinishTaskList<int>(task.WMSTASK, item.Station));
-                    }
-                    //两个任务一起创建
-                    db.Default.SaveChanges();
-                });
-
-                //检查对应的任务是否已创建成功
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.WMSTASK == finishTask.FinishCode);
-                        if (task == null) continue;
-
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = task.ADDRFROM.ToShort();
-                        finishTask.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                        finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finishTask.Station.Data.CmdType = IstationCmdType.扫码入库;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1157";
-        }
-    }
-
-    /// <summary>
-    /// BOPP巷道分配
-    /// </summary>
-    [WorkTitle(typeof(BOPPHandler), "BOPP巷道分配")]
-    public class Bopp巷道分配 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                var code = stationDeviceGroup.Entity.CODE;
-                //两个设备都必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待任务执行--凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new WarnException($"设备运行中");
-
-                //成功分配巷道的任务的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                //变更数据库信息
-                DB.Do(db =>
-                {
-                    var devise = stationDeviceGroup.GetAddressValid();
-                    if (!devise.Any()) return; //无可执行任务
-                    var taskList = devise.ValidTaskCheck(db);
-
-                    var res = WMS.GetTunnelList(taskList.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                    if (string.IsNullOrEmpty(res.TunnelNum)) throw new WarnException($"WMS未返回巷道");
-
-                    var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                    var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                    var tunnelInfos = new List<TunnelInfo>();
-
-                    foreach (var item in tunnels)
-                    {
-                        //当前巷道的取货点
-                        var allIn = Device.Where(v => v.Is(DF.SRMBOPP取货)) //一楼所有取货点
-                                          .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
-                                          .Select(v => v.CODE)
-                                          .ToList();
-                        //下一个目标地址包含取货点的设备,此时获得的数据是旋转台
-                        var turntable = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && allIn.Contains(p.NEXT.CODE))).Select(v => v.CODE);
-                        //获得RGV的交货点
-                        StationDevice rgvDeliveryPoint = null;
-                        if (item.CODE == "TY1")
-                        {
-                            rgvDeliveryPoint = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && turntable.Contains(p.NEXT.CODE)))
-                                      .Select(v => v.Create<StationDevice>()) //取所有可以到达取货点设备的信息
-                                      .Where(v => v.Data3.Status.HasFlag(StationStatus.自动))//筛选出空闲的路径点,此处因输送机都是一个动力,因此可以先找路径点再找设备组
-                                      .Distinct()
-                                      .FirstOrDefault();//去一次重
-                        }
-                        else
-                        {
-                            rgvDeliveryPoint = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && turntable.Contains(p.NEXT.CODE)))
-                                     .Select(v => v.Create<StationDevice>()) //取所有可以到达取货点设备的信息
-                                     .Where(v => !v.Data3.Status.HasFlag(StationStatus.运行状态位)
-                                              && !v.Data2.Status.HasFlag(IstationStatus.光电状态)
-                                              && v.Data2.Tasknum < 10000
-                                              && v.Data3.Status.HasFlag(StationStatus.自动))//筛选出空闲的路径点,此处因输送机都是一个动力,因此可以先找路径点再找设备组
-                                     .Distinct()
-                                     .FirstOrDefault();//去一次重
-                        }
-                        if (rgvDeliveryPoint == null) continue;
-                        var taskInStation = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => d.MEMBER == rgvDeliveryPoint.Entity)).MinBy(p => p.CODE);
-                        //只能有一组任务的下一个地址是交货点
-                        if (db.Default.Set<WCS_TASK>().Any(v => v.ADDRNEXT == taskInStation.CODE && v.STATUS < TaskStatus.已完成)) continue;
-                        //RGV是否有正在前往这个地址的任务
-                        var rgvList = Device.Where(v => v.Is(DF.BOPPRGV)).Select(v => v.Create<RGVDevice>());
-
-                        var rgvTaskCount = ProtocolProxy.YGWMS150Redis.Get("BoppRgvTaskCount").ToInt();
-                        if (rgvList.Count(v => (!v.Data2.SystemStatus.HasFlag(WCS.Entity.Protocol.RGV.RGVRunStatus.空闲) || !v.Data2.WorkMode.HasFlag(WCS.Entity.Protocol.RGV.RGVMode.自动))
-                                            && v.Data2.TaskType_1 == WCS.Entity.Protocol.RGV.RGVTaskType.放货
-                                            && v.Data2.DestPosition_1 == taskInStation?.CODE.Replace("G", "").ToShort()) > rgvTaskCount) continue;
-                        tunnelInfos.Add(new TunnelInfo
-                        {
-                            Tunnel = item,
-                            taskIN = taskInStation, //找到放货点设备所在组
-                            SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                        });
-                    }
-                    //筛选出优先级最高的可用巷道
-                    var tunnelInfo = tunnelInfos.Where(v => { try { return (v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程) || v.SRM.Entity.CODE == "SRM1"; } catch { return false; } }).MinBy(v => tunnelNo.IndexOf(v.Tunnel.CODE));
-
-                    if (tunnelInfo == null) throw new WarnException("无可用巷道");
-
-                    //开始变更任务信息
-                    foreach (var item in devise)
-                    {
-                        var dev = Device.Find(item.Station.Entity.CODE).Create<StationDevice>();
-                        var task = taskList.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-                        if (task == null) throw new WarnException($"WCS无该任务{dev.Data2.Tasknum}--{dev.Entity.CODE}");
-
-                        task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                        task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                        task.ADDRNEXT = tunnelInfo.taskIN.CODE;
-                        task.TaskGroupKey = res.WMSTaskGroupKey;
-                        task.ADDRTO = task.DEVICE;
-                        var msg = $"下达从G23移动至{dev.Data.Goodsend}的PLC指令。同时将任务分配至[{task.TUNNEL}]-[{task.DEVICE}]";
-                        msg += $"[{dev.Data.Tasknum}][G23][{dev.Data.Goodsend}][{tunnelInfo.SRM.Entity.CODE}][{dev.Data.VoucherNo}[{dev.Data2.VoucherNo}]";
-                        task.CreateStatusLog(db, msg, this.GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, item.Station));
-                    }
-                    db.Default.SaveChanges();
-                });
-
-                // 开始将任务信息写入到设备
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().Find(finishTask.FinishCode);
-                        if (task == null)
-                        {
-                            InfoLog.INFO_WarnDb($"WCS未找到任务{finishTask.FinishCode}", finishTask.Station.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                            continue;
-                        }
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = stationDeviceGroup.Entity.CODE.Replace("G", "").ToShort();
-                        finishTask.Station.Data.Goodsend = task.ADDRNEXT.Replace("G", "").ToShort();
-                        finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finishTask.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G23";
-        }
-    }
-
-    /// <summary>
-    /// 涂布入库旋转台二次分配巷道
-    /// </summary>
-    [WorkTitle(typeof(BOPPHandler), "BOPP入库旋转台二次分配巷道")]
-    public class Bopp入库旋转台二次分配巷道 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                var code = stationDeviceGroup.Entity.CODE;
-
-                //两个设备都必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待任务执行--凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new WarnException($"设备运行中");
-                //成功分配巷道的任务的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                //变更数据库信息
-                DB.Do(db =>
-                {
-                    var devise = stationDeviceGroup.GetAddressValid();
-                    if (!devise.Any()) return; //无可执行任务
-                    var taskList = devise.ValidTaskCheck(db);
-
-                    var res = WMS.GetTunnelList(taskList.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                    if (string.IsNullOrEmpty(res.TunnelNum)) throw new WarnException($"WMS未返回巷道");
-
-                    var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                    var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                    var tunnelInfos = new List<TunnelInfo>();
-                    var setting = new JsonSerializerSettings();
-                    setting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
-                    setting.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
-                    foreach (var item in tunnels)
-                    {
-                        //当前巷道的取货点
-                        var allIn = Device.Where(v => v.Is(DF.SRMBOPP取货))
-                                          .Where(v => v.ROUTES.Any(p => p.NEXT.CODE == item.CODE)) //下一个点为当前巷道的取货点
-                                          .Select(v => v.CODE)
-                                          .ToList();
-                        //下一个目标地址包含取货点的设备,此时获得的数据是旋转台
-                        var turntable = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && allIn.Contains(p.NEXT.CODE)))
-                                              .Where(v => stationDeviceGroup.Items.Any(p => p.Entity == v))// 筛选出包含在当前设备组的设备
-                                              .Distinct()
-                                              .FirstOrDefault();//去一次重
-                        if (turntable == null) continue;
-                        var dev = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => allIn.Contains(d.MEMBER.CODE))).MinBy(p => p.CODE);
-                        tunnelInfos.Add(new TunnelInfo
-                        {
-                            Tunnel = item,
-                            taskIN = dev, //找到放货点设备所在组
-                            SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                        });
-                    }
-                    //筛选出优先级最高的可用巷道
-                    var tunnelInfo = tunnelInfos.Where(v =>
-                    {
-                        try
-                        {
-                            return (v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程 && v.SRM.Data2.SRMStatus == SCRunStatus.空闲) || v.SRM.Entity.CODE == "SRM1" || v.SRM.Entity.CODE == "SRM2";
-                        }
-                        catch { return false; }
-                    }).MinBy(v => tunnelNo.IndexOf(v.Tunnel.CODE));
-                    if (tunnelInfo == null) throw new WarnException("无可用巷道");
-
-                    //开始变更任务信息
-                    foreach (var item in devise)
-                    {
-                        var dev = Device.Find(item.Station.Entity.CODE).Create<StationDevice>();
-                        var task = taskList.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-                        if (task == null) throw new WarnException($"WCS无该任务{dev.Data2.Tasknum}--{dev.Entity.CODE}");
-
-                        task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                        task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                        task.ADDRNEXT = dev.Entity.GetPath(task.DEVICE).CODE;
-                        task.TaskGroupKey = res.WMSTaskGroupKey;
-                        task.ADDRTO = task.DEVICE;
-                        var msg = $"下达从{stationDeviceGroup.Entity.CODE}移动至{dev.Data.Goodsend}的PLC指令。同时将任务分配至[{task.TUNNEL}]-[{task.DEVICE}]";
-                        msg += $"[{dev.Data.Tasknum}][{stationDeviceGroup.Entity.CODE}][{dev.Data.Goodsend}][{tunnelInfo.SRM.Entity.CODE}][{dev.Data.VoucherNo}[{dev.Data2.VoucherNo}]";
-                        task.CreateStatusLog(db, msg, GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, item.Station));
-                    }
-                    db.Default.SaveChanges();
-                });
-
-                // 开始将任务信息写入到设备
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().Find(finishTask.FinishCode);
-                        if (task == null) continue;
-
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = stationDeviceGroup.Entity.CODE.Replace("G", "").ToShort();
-                        finishTask.Station.Data.Goodsend = finishTask.Station.Entity.GetPath(task.DEVICE).CODE.ToShort();
-                        finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finishTask.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return _devCodes.Contains(dev.CODE);
-        }
-
-        private readonly List<string> _devCodes = new() { "G1190", "G1199", "G1208", "G1217", "G1225" };
-    }
-}

+ 0 - 319
Projects/永冠OPP/WCS.Service/Works/Station/一楼入库.cs

@@ -1,319 +0,0 @@
-using DBHelper;
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.SRM;
-using WCS.Service.Extensions;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Works.Station
-{
-    [WorkTitle(typeof(ProductHandler), "扫码入库")]
-    internal class 扫码入库 : Work<StationDeviceGroup>
-    {
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1028";
-        }
-
-        protected override void Do(StationDeviceGroup obj)
-        {
-            var timer = new Stopwatch();
-            timer.Start();
-            obj.EX(obj =>
-                {
-                    if (!obj.BcrStationIsForbid()) return;
-
-                    //设备组无论单卷还是双卷都必须满足的条件
-                    if (obj.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待任务执行--凭证号不一致");
-                    if (obj.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new WarnException($"设备运行中");
-
-                    //成功创建的任务
-                    var finishTaskList = new List<FinishTaskList<int>>();
-                    var devs = obj.GetBcrValid();
-                    if (!devs.Valid(obj.Entity.CODE)) return;
-                   
-                    var infos = devs.GetWMSInTask();
-                    if (!infos.Any()) throw new WarnException($"{obj.Entity.CODE}: WMS未返回结果");
-                    //创建对应的任务
-                    DB.Do(db =>
-                    {
-                        foreach (var item in devs)
-                        {
-                            var dev = item.Station;
-                            var next = dev.Entity.GetPath("SRM").CODE;
-                            var info = infos.FirstOrDefault(v => item.FinishCode.Contains(v.ContainerCode + "}"));
-                            if (db.Default.Set<WCS_TASK>().AsNoTracking().Any(v => v.BARCODE == info.ContainerCode && v.STATUS < TaskStatus.已完成 && v.TYPE == TaskType.入库))
-                                throw new WarnException($"生产条码{info.ContainerCode}存在未完成任务,请检查是否为标签卡重复使用");
-
-                            var task = new WCS_TASK();
-                            task.BARCODE = info.ContainerCode;
-                            task.TYPE = TaskType.入库;
-                            task.STATUS = TaskStatus.执行中;
-                            task.ADDRFROM = dev.Entity.CODE;
-                            task.ADDRTO = info.EndPostion;
-                            task.STARTTIME = DateTime.Now;
-                            task.UPDATEUSER = "WCS";
-                            task.UPDATETIME = DateTime.Now;
-                            task.WMSTASK = int.Parse(info.WMSTaskNum);
-                            task.TaskGroupKey = info.TaskGroupKey;
-                            task.ADDRNEXT = next;
-                            task.HEIGHT = dev.Data2.GoodsSize;
-                            task.FLOOR = 1;
-
-                            db.Default.Set<WCS_TASK>().Add(task);
-                            finishTaskList.Add(new FinishTaskList<int>(task.WMSTASK, item.Station));
-                        }
-                        //两个任务一起创建
-                        db.Default.SaveChanges();
-                    });
-
-                    //检查对应的任务是否已创建成功
-                    DB.Do(db =>
-                    {
-                        foreach (var finishTask in finishTaskList)
-                        {
-                            var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.WMSTASK == finishTask.FinishCode);
-                            if (task == null) continue;
-
-                            finishTask.Station.Data.Tasknum = task.ID;
-                            finishTask.Station.Data.Goodsstart = task.ADDRFROM.ToShort();
-                            finishTask.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                            finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                            finishTask.Station.Data.CmdType = IstationCmdType.扫码入库;
-                            finishTask.Station.Data.VoucherNo++;
-                        }
-                    });
-                    if (finishTaskList.Any())
-                    {
-                        timer.Stop();
-                        InfoLog.INFO_TIMING($"{obj.Entity.CODE}--扫码入库,耗时{timer.ElapsedMilliseconds}");
-                    }
-                });
-        }
-    }
-
-    [WorkTitle(typeof(ProductHandler), "一楼分配巷道")]
-    internal class 巷道分配 : Work<StationDeviceGroup>
-    {
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1030";
-        }
-
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(obj =>
-            {
-                var code = obj.Entity.CODE;
-                //两个设备都必须满足的条件
-                if (obj.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException("等待任务执行,凭证号不一致");
-                if (obj.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-
-                //成功分配巷道的任务的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                var devs = obj.Items.Where(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Request == IstationRequest.请求分配目标地址)
-                                           .Where(v => v.Data2.Tasknum > 10000 && v.Data2.Goodsend != 0);
-                if (!devs.Any()) return; //无可执行任务
-                var taskIds = devs.Select(dev => dev.Data2.Tasknum).ToList();
-                var devConvs = Device.Where(v => v.IsConv());
-                //变更数据库信息
-                DB.Do(db =>
-                {
-                    var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-
-                    taskList.ValidTaskCheck(devs.Count(), db);
-
-                    var res = WMS.GetTunnelList(taskList.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                    if (string.IsNullOrEmpty(res.TunnelNum)) throw new WarnException($"WMS未返回巷道");
-                    var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                    var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                    List<TunnelInfo> tunnelInfos = new List<TunnelInfo>();
-                    foreach (var item in tunnels)
-                    {
-                        //当前巷道的取货点
-                        var allIn = Device.Where(v => v.Is(DF.SRM二级品取货)) //二楼所有取货点
-                                          .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
-                                          .Select(v => v.CODE)
-                                          .ToList();
-
-                        //下一个目标地址包含取货点的设备,此时获得的数据是旋转台
-                        var turntable = devConvs.Where(v => v.ROUTES.Any(p => p.NEXT != null && allIn.Contains(p.NEXT.CODE))).Select(v => v.CODE);
-
-                        var putStation = devConvs.Where(v => v.ROUTES.Any(p => p.NEXT != null && turntable.Contains(p.NEXT.CODE))) //下一个目标地址包含取货点的设备
-                                      .Select(v => v.Create<StationDevice>()) //取所有可以到达取货点设备的信息
-                                      .Where(v => !v.Data3.Status.HasFlag(StationStatus.运行状态位) && !v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000)//筛选出空闲的路径点,此处因输送机都是一个动力,因此可以先找路径点再找设备组
-                                      .Distinct()
-                                      .FirstOrDefault();//去一次重
-                        if (putStation == null) continue;
-                        var taskInStation = Device.Where(v => v.IsDevGroup()).Where(p => p.DEVICEGROUP.Any(d => d.MEMBER == putStation.Entity)).OrderBy(p => p.CODE).FirstOrDefault();
-                        //RGV是否有正在前往这个地址的任务
-                        var rgv8 = Device.Find("RGV8").Create<RGVDevice>();
-                        if ((!rgv8.Data2.SystemStatus.HasFlag(WCS.Entity.Protocol.RGV.RGVRunStatus.空闲) || !rgv8.Data2.WorkMode.HasFlag(WCS.Entity.Protocol.RGV.RGVMode.自动))
-                           && rgv8.Data2.DestPosition_1 == taskInStation.CODE.Replace("G", "").ToShort()) continue;
-                        tunnelInfos.Add(new TunnelInfo
-                        {
-                            Tunnel = item,
-                            taskIN = taskInStation, //找到放货点设备所在组
-                            SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                        });
-                    }
-                    //筛选出优先级最高的可用巷道
-                    var tunnelInfo = tunnelInfos.Where(v => { try { return v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程 && v.SRM.Data2.SRMStatus == SCRunStatus.空闲; } catch { return false; } })
-                                                .Where(v => !db.Default.Set<WCS_TASK>().Any(p => p.Priority > 0 && p.DEVICE == v.SRM.Entity.CODE && p.STATUS < TaskStatus.堆垛机完成))
-                                                .OrderBy(v => tunnelNo.IndexOf(v.Tunnel.CODE)).FirstOrDefault();
-                    if (tunnelInfo == null) throw new WarnException("无可用巷道");
-
-                    //开始变更任务信息
-                    foreach (var item in devs)
-                    {
-                        var dev = Device.Find(item.Entity.CODE).Create<StationDevice>();
-                        var task = taskList.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-                        if (task == null) throw new WarnException($"WCS无该任务{dev.Data2.Tasknum}--{dev.Entity.CODE}");
-
-                        task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                        task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                        task.ADDRNEXT = tunnelInfo.taskIN.CODE;
-                        task.TaskGroupKey = res.WMSTaskGroupKey;
-                        task.ADDRTO = task.DEVICE;
-                        task.CreateStatusLog(db, $"一次分配至堆垛机{task.DEVICE}", this.GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, item.Entity.Create<StationDevice>()));
-                    }
-
-                    db.Default.SaveChanges();
-                });
-
-                // 开始将任务信息写入到设备
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().Find(finishTask.FinishCode);
-                        if (task == null) continue;
-
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = 1030;
-                        finishTask.Station.Data.Goodsend = task.ADDRNEXT.Replace("G", "").ToShort();
-                        finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finishTask.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-    }
-
-    [WorkTitle(typeof(ProductHandler), "一楼入库旋转台二次分配巷道")]
-    internal class 一楼入库旋转台二次分配巷道 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(obj =>
-            {
-                var code = obj.Entity.CODE;
-
-                //两个设备都必须满足的条件
-                if (obj.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException("等待执行任务--凭证号不一致");
-                if (obj.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-                //成功分配巷道的任务的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                //变更数据库信息
-                DB.Do(db =>
-                {
-                    var devs = obj.Items.Where(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Request == IstationRequest.请求分配目标地址)
-                                       .Where(v => v.Data2.Tasknum > 10000);
-                    if (!devs.Any()) return; //无可执行任务
-                    var taskIds = devs.Select(dev => dev.Data2.Tasknum).ToList();
-                    var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-
-                    taskList.ValidTaskCheck(devs.Count(), db);
-
-                    var res = WMS.GetTunnelList(taskList.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                    if (string.IsNullOrEmpty(res.TunnelNum)) throw new WarnException($"WMS未返回巷道");
-                    var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                    var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                    List<TunnelInfo> tunnelInfos = new List<TunnelInfo>();
-                    foreach (var item in tunnels)
-                    {
-                        //当前巷道的取货点
-                        var allIn = Device.Where(v => v.Is(DF.SRM二级品取货)) //一楼所有取货点
-                                      .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
-                                      .Select(v => v.CODE)
-                                      .ToList();
-                        //下一个目标地址包含取货点的设备,此时获得的数据是旋转台
-                        var turntable = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && allIn.Contains(p.NEXT.CODE)))
-                                          .Where(v => obj.Items.Any(p => p.Entity == v))// 筛选出包含在当前设备组的设备
-                                          .Distinct()
-                                          .FirstOrDefault();//去一次重
-                        if (turntable == null) continue;
-                        var dev = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => d.MEMBER == turntable)).OrderBy(p => p.CODE).FirstOrDefault();
-
-                        tunnelInfos.Add(new TunnelInfo
-                        {
-                            Tunnel = item,
-                            taskIN = dev, //找到放货点设备所在组
-                            SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                        });
-                    }
-                    //筛选出优先级最高的可用巷道
-                    var tunnelInfo = tunnelInfos.Where(v => { try { return v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程 && v.SRM.Data2.SRMStatus == SCRunStatus.空闲; } catch { return false; } })
-                                            .OrderBy(v => tunnelNo.IndexOf(v.Tunnel.CODE)).FirstOrDefault();
-                    if (tunnelInfo == null) throw new WarnException("无可用巷道");
-
-                    //开始变更任务信息
-                    foreach (var item in devs)
-                    {
-                        var dev = item.Entity.Create<StationDevice>();
-                        var task = taskList.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-                        if (task == null) throw new WarnException($"WCS无该任务{dev.Data2.Tasknum}--{dev.Entity.CODE}");
-
-                        task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                        task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                        task.ADDRNEXT = tunnelInfo.taskIN.CODE;
-                        task.TaskGroupKey = res.WMSTaskGroupKey;
-                        task.ADDRTO = task.DEVICE;
-                        task.CreateStatusLog(db, $"二次分配至堆垛机{task.TUNNEL}", this.GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, dev));
-                    }
-                    db.Default.SaveChanges();
-                });
-
-                // 开始将任务信息写入到设备
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().Find(finishTask.FinishCode);
-                        if (task == null) continue;
-
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = obj.Entity.CODE.Replace("G", "").ToShort();
-                        finishTask.Station.Data.Goodsend = finishTask.Station.Entity.GetPath(task.DEVICE).CODE.ToShort();
-                        finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finishTask.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return devCodes.Contains(dev.CODE);
-        }
-
-        private List<string> devCodes = new List<string>() { "G1038", "G1047", "G1056", "G1065" };
-    }
-}

+ 0 - 206
Projects/永冠OPP/WCS.Service/Works/Station/一楼出库.cs

@@ -1,206 +0,0 @@
-using DBHelper;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Service.Extensions;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Works.Station
-{
-    [WorkTitle(typeof(ProductHandler), "一楼出库堆垛机放货完成后分配下一个地址")]
-    public class 一楼出库 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待任务执行--凭证号不一致");
-
-                //成功处理的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-                var devise = new List<FinishTaskList<string>>();
-                foreach (var dev in stationDeviceGroup.Items)
-                {
-                    //没有请求
-                    if (dev.Data2.Request != IstationRequest.堆垛机放货完成请求目标地址)
-                    {
-                        InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}无请求-堆垛机放货完成请求--4");
-                        continue;
-                    }
-                    //没有光电
-                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    }
-                    devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                }
-                if (!devise.Any()) return;
-
-                DB.Do(db =>
-                {
-                    foreach (var dev in devise)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.TYPE == TaskType.出库 && v.SRMSTATION == dev.FinishCode && v.STATUS == TaskStatus.堆垛机完成) ?? throw new WarnException("无任务");
-                        var tasks = db.Default.Set<WCS_TASK>().Where(v => v.TaskGroupKey == task.TaskGroupKey);
-                        if (tasks.Count() != devise.Count) throw new WarnException($"可执行任务数{devise.Count},实际任务数{tasks.Count()}");
-                        if (tasks.Any(v => v.STATUS != TaskStatus.堆垛机完成 && v.STATUS != TaskStatus.执行中)) throw new WarnException("任务异常,同组任务状态不为堆垛机完成或执行中");
-
-                        task.STATUS = TaskStatus.执行中;
-                        task.CreateStatusLog(db,$"堆垛机放货点分配目标地址{task.ADDRNEXT}", GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, dev.Station));
-                    }
-                    db.Default.SaveChanges();
-                });
-
-                DB.Do(db =>
-                {
-                    foreach (var finish in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == finish.FinishCode);
-                        if (task == null) continue;
-                        finish.Station.Data.Tasknum = task.ID;
-                        finish.Station.Data.Goodsstart = finish.Station.Entity.CODE.ToShort();
-                        finish.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                        finish.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finish.Station.Data.CmdType = IstationCmdType.堆垛机放货完成请求目标地址;
-                        finish.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return _devCodes.Contains(dev.CODE);
-        }
-
-        //月台堆垛机放货设备组
-        private readonly List<string> _devCodes = new() { "G1473", "G1474", "G1493", "G1491", "G1520", "G1522", "G1545", "G1451" };
-    }
-
-    [WorkTitle(typeof(ProductHandler), "月台出货口完成任务")]
-    public class 月台完成任务 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                //当前组有一个运行的设备就停止执行
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("设备运行中");
-                if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态))) throw new DoException("设备停止运行,但有光电");
-                //此处逻辑为货物离开后报完成
-                var devise = new List<FinishTaskList<string>>();
-
-                foreach (var dev in stationDeviceGroup.Items)
-                {
-                    if (dev.Data2.Request != IstationRequest.月台出库口任务完成)
-                    {
-                        InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}无请求-月台出库口任务完成--3");
-                        continue;
-                    }
-                    if (dev.Data2.Tasknum < 10000)
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求无任务号", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    };
-                    devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                }
-                //成功处理的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                DB.Do(db =>
-                {
-                    foreach (var dev in devise)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == dev.Station.Data2.Tasknum);
-                        if (task?.STATUS == TaskStatus.新建) throw new WarnException($"{task.ID}任务状态错误");
-
-                        task!.STATUS = TaskStatus.已完成;
-                        task.ENDTIME = System.DateTime.Now;
-                        task.UPDATEUSER = "WCS";
-                        task.CreateStatusLog(db,$"任务完成", this.GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, dev.Station));
-                    }
-                    db.Default.SaveChanges();
-                });
-                DB.Do(db =>
-                {
-                    foreach (var finish in from finish in finishTaskList let task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == finish.FinishCode) select finish)
-                    {
-                        finish.Station.Data.CmdType = IstationCmdType.月台出库口任务完成;
-                        finish.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return _devCodes.Contains(dev.CODE);
-        }
-
-        private readonly List<string> _devCodes = new() { "G1469", "G1561", "G1538", "G1574", "G1509" };
-    }
-
-    [WorkTitle(typeof(ProductHandler), "转圈交互点分配目标地址")]
-    public class 转圈交互点分配目标地址 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待任务执行--凭证号不一致");
-
-                var devise = new List<FinishTaskList<string>>();
-                foreach (var dev in stationDeviceGroup.Items)
-                {
-                    //没有请求
-                    if (dev.Data2.Request != IstationRequest.请求分配目标地址)
-                    {
-                        InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}无请求-分配目标地址--2");
-                        continue;
-                    }
-                    //没有光电
-                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    };
-                    if (dev.Data2.Tasknum < 10000)
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求有光电无任务", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    }
-                    devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                }
-
-                DB.Do(db =>
-                {
-                    foreach (var dev in devise)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == dev.Station.Data2.Tasknum) ?? throw new WarnException("无任务");
-                        var tasks = db.Default.Set<WCS_TASK>().Where(v => v.TaskGroupKey == task.TaskGroupKey);
-                        if (devise.Count != tasks.Count()) throw new WarnException($"可执行任务数{devise.Count},实际任务数{tasks.Count()}");
-                        dev.Station.Data.Tasknum = task.ID;
-                        dev.Station.Data.Goodsstart = dev.Station.Entity.CODE.ToShort();
-                        dev.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                        dev.Station.Data.Goodsnum = devise.Count.ToShort();
-                        dev.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        dev.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1589";
-        }
-    }
-}

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

@@ -1,596 +0,0 @@
-using DBHelper;
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.SRM;
-using WCS.Service.Extensions;
-using WCS.Service.Handlers;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Works.Station
-{
-    /// <summary>
-    /// 涂布入库AGV交互
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布入库AGV交互")]
-    public class 涂布入库agv交互 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                var station = stationDeviceGroup.Entity.CODE;
-
-                #region 处理新增AGV任务
-
-                DB.Do(db =>
-                {
-                    //找到所有的AGV任务
-                    var agvTasks = db.Default.Set<WCS_AGVTask>().Where(v => v.TaskType == AGVTaskType.入库)
-                    .Where(v => v.Status < AGVTaskStatus.完成).OrderByDescending(v => v.Status).ThenBy(v => v.CreateTime).ToArray();
-
-                    foreach (var tasking in agvTasks)
-                    {
-                        var position = tasking.Position;
-                        if (!ProtocolProxy.AllDatas.ContainsKey(position))
-                            ProtocolProxy.AllDatas[position] = new ProdLineData();
-                        var pld = ProtocolProxy.AllDatas[position] as ProdLineData;
-                        pld!.Frame = LogicHandler.Frame;
-                        pld.Code = position;
-                        pld.TaskList.Add(tasking);
-
-                        if (tasking.Status == AGVTaskStatus.新建)
-                        {
-                            tasking.Status = AGVTaskStatus.执行;
-                            tasking.UpdateTime = DateTime.Now;
-                            db.Default.SaveChanges();
-                            tasking.AGVStatusChange(AGVTaskStatus.执行, "确认执行");
-                        }
-                        //agv到达指定位置给确认后分配站台
-                        else if (tasking.Status == AGVTaskStatus.执行 && tasking.AGVStatus == AGVTaskStatus.确认 && string.IsNullOrEmpty(tasking.Station))
-                        {
-                            //判断提升机是否被禁用
-                            if (!stationDeviceGroup.BcrStationIsForbid()) continue;
-
-                            if (stationDeviceGroup.Items.Any(v => !v.Data3.Status.HasFlag(StationStatus.自动)))
-                            {
-                                InfoLog.INFO_INFO($"{station}手动状态");
-                                continue;
-                            }
-
-                            var qty = db.Default.Set<WCS_AGVTask>().Where(v => v.TaskType == AGVTaskType.入库 && v.Status > AGVTaskStatus.新建 && v.Status < AGVTaskStatus.完成);
-                            if (qty.Any(v => v.Station == stationDeviceGroup.Entity.CODE) || agvTasks.Any(v => v.Station == stationDeviceGroup.Entity.CODE))
-                            {
-                                InfoLog.INFO_WARN($"已有到达{stationDeviceGroup.Entity.CODE}放货任务,暂停AGV站台分配");
-                                continue;
-                            }
-
-                            //if (qty.Count(v => v.Station == stationDeviceGroup.Entity.CODE) > qty.Count(v => v.Station != stationDeviceGroup.Entity.CODE && !string.IsNullOrEmpty(v.Station)))
-                            //{
-                            //    InfoLog.INFO_INFO($"{station}触发均分");
-                            //    continue;
-                            //}
-
-                            tasking.Station = stationDeviceGroup.Entity.CODE;
-                            tasking.Status = AGVTaskStatus.执行;
-                            tasking.UpdateTime = DateTime.Now;
-                            db.Default.SaveChanges();
-                            tasking.AGVStatusChange(AGVTaskStatus.执行, "分配放货点");
-                        }
-                        else if (tasking.Status < tasking.AGVStatus)
-                        {
-                            if (tasking.Station != stationDeviceGroup.Entity.CODE)
-                            {
-                                InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}不是当前站台的AGV任务");
-                                continue;
-                            }
-                            if (tasking.AGVStatus == AGVTaskStatus.请求_允许)
-                            {
-                                if (stationDeviceGroup.Items.Any(v => !v.Data3.Status.HasFlag(StationStatus.自动)))
-                                {
-                                    InfoLog.INFO_INFO("不在自动状态");
-                                    continue;
-                                }
-                                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位)))
-                                {
-                                    InfoLog.INFO_INFO("设备运行中");
-                                    continue;
-                                }
-                                if (stationDeviceGroup.Items.Any(v => !v.Data3.Status.HasFlag(StationStatus.高位)))
-                                {
-                                    InfoLog.INFO_WarnDb("不在高位", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-                                if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态)))
-                                {
-                                    InfoLog.INFO_WarnDb("AGV请求放货,但有光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-                                if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.AGV放货完成信号)))
-                                {
-                                    InfoLog.INFO_WarnDb("AGV放货完成信号未清除", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-                                if (stationDeviceGroup.Items.Any(v => v.Data2.Tasknum > 0))
-                                {
-                                    InfoLog.INFO_WarnDb("已有WCS任务号", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-
-                                if (db.Default.Set<WCS_AGVTask>().Any(v => v.Station == tasking.Station && v.Status >= AGVTaskStatus.请求_允许 && v.Status < AGVTaskStatus.完成扫码 && v.ID != tasking.ID)) //只能允许一个
-                                {
-                                    InfoLog.INFO_WarnDb("上一个允许放货的AGV任务未完成", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-                                //判断1435扫码位置条件
-                                var judge = Device.Find("1435").Device<IStation520, IStation521, IStation523>();
-                                if (stationDeviceGroup.Entity.CODE == "G1394")
-                                {
-                                    if (!judge.Data3.Status.HasFlag(StationStatus.自动))
-                                    {
-                                        InfoLog.INFO_INFO("不在自动状态1435");
-                                        continue;
-                                    }
-
-                                    if (judge.Data3.Status.HasFlag(StationStatus.运行状态位))
-                                    {
-                                        InfoLog.INFO_INFO("设备运行中1435");
-                                        continue;
-                                    }
-
-                                    //判断是否有货
-                                    if (judge.Data2.Status.HasFlag(IstationStatus.光电状态))
-                                    {
-                                        InfoLog.INFO_WarnDb("前方有光电,不可放货", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                        continue;
-                                    }
-
-                                    if (judge.Data2.Tasknum > 0)
-                                    {
-                                        InfoLog.INFO_WarnDb("已 有WCS任务号", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                        continue;
-                                    }
-                                }
-
-                                tasking.Status = tasking.AGVStatus;
-                                tasking.UpdateTime = DateTime.Now;
-                                db.Default.SaveChanges();
-                                tasking.AGVStatusChange(tasking.AGVStatus, "允许放货");
-                            }
-                            else if (tasking.AGVStatus == AGVTaskStatus.取放完成)
-                            {
-                                if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.AGV放货完成信号)))
-                                {
-                                    InfoLog.INFO_WarnDb("AGV放货完成信号未清楚", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-                                if (!stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态)))
-                                {
-                                    InfoLog.INFO_WarnDb("放货完成无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                    continue;
-                                }
-
-                                tasking.Status = tasking.AGVStatus;
-                                tasking.UpdateTime = DateTime.Now;
-                                db.Default.SaveChanges();
-                                foreach (var dev in stationDeviceGroup.Items)
-                                {
-                                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                                    {
-                                        InfoLog.INFO_WarnDb($"AGV请求放货,但设备{dev.Entity.CODE}无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                        continue;
-                                    }
-
-                                    dev.Data.Goodsnum = (short)tasking.Goodsnum;
-                                    dev.Data.Istation521Status = IstationStatus.AGV放货完成信号;
-                                }
-                                tasking.AGVStatusChange(tasking.AGVStatus, "允许设备顶升下降");
-                            }
-                            else if (Ltc.Do(tasking, v => v.AGVStatus == AGVTaskStatus.完成))
-                            {
-                                tasking.Status = tasking.AGVStatus;
-                                tasking.UpdateTime = DateTime.Now;
-                                db.Default.SaveChanges();
-                                var devise = Device.Find(tasking.Station).Create<StationDeviceGroup>();
-                                foreach (var dev in devise.Items)
-                                {
-                                    dev.Data.Goodscode = tasking.ID;
-                                }
-                                tasking.AGVStatusChange(tasking.AGVStatus, "完成任务");
-                            }
-                            else if (Ltc.Do(tasking, v => v.AGVStatus == AGVTaskStatus.取消))
-                            {
-                                tasking.Status = tasking.AGVStatus;
-                                tasking.UpdateTime = DateTime.Now;
-                                db.Default.SaveChanges();
-                                tasking.AGVStatusChange(tasking.AGVStatus, "取消任务");
-                            }
-                        }
-                    }
-                });
-
-                #endregion 处理新增AGV任务
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE is "G1394" or "G1386";
-        }
-    }
-
-    /// <summary>
-    /// 涂布扫码入库
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布入库")]
-    public class 涂布扫码入库 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                if (!stationDeviceGroup.BcrStationIsForbid()) return;
-
-                //设备组无论单卷还是双卷都必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待任务执行--凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new WarnException($"设备运行中");
-
-                if (stationDeviceGroup.Entity.CODE == "G1386")
-                {
-                    if (stationDeviceGroup.Items.Any(v => !v.Data3.Status.HasFlag(StationStatus.低位))) throw new DoException("不在低位");
-                }
-
-                var devise = stationDeviceGroup.GetBcrValid();
-                if (!devise.Valid(stationDeviceGroup.Entity.CODE)) return;
-                var infos = devise.GetWMSInTask();
-                WCS_AGVTask agvTask = null;
-
-                //成功创建的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-                //创建对应的任务
-                DB.Do(db =>
-                {
-                    if (!stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.手动入库)))
-                    {
-                        if (stationDeviceGroup.Entity.CODE == "G1435")
-                        {
-                            agvTask = db.Default.Set<WCS_AGVTask>().FirstOrDefault(v => v.Status == AGVTaskStatus.完成 && v.Station == "G1394") ?? throw new WarnException("无完成AGV任务");
-                        }
-                        else
-                        {
-                            agvTask = db.Default.Set<WCS_AGVTask>().FirstOrDefault(v => v.Status == AGVTaskStatus.完成 && v.Station == stationDeviceGroup.Entity.CODE) ?? throw new WarnException("无完成AGV任务");
-                        }
-
-                        if (agvTask.Status != AGVTaskStatus.完成扫码)
-                        {
-                            agvTask.Status = AGVTaskStatus.完成扫码;
-                            agvTask.UpdateTime = DateTime.Now;
-                        }
-                    }
-
-                    foreach (var item in devise)
-                    {
-                        var dev = item.Station;
-                        var next = dev.Entity.GetPath("SRM");
-                        var info = infos.FirstOrDefault(v => item.FinishCode.Contains(v.ContainerCode + "}"));
-                        if (db.Default.Set<WCS_TASK>().AsNoTracking().Any(v => v.BARCODE == info.ContainerCode && v.STATUS < TaskStatus.已完成 && v.TYPE == TaskType.入库))
-                            throw new WarnException($"生产条码{info?.ContainerCode}存在未完成任务,请检查是否为标签卡重复使用");
-
-                        var task = new WCS_TASK
-                        {
-                            BARCODE = info?.ContainerCode,
-                            TYPE = TaskType.入库,
-                            STATUS = TaskStatus.执行中,
-                            ADDRFROM = dev.Entity.CODE,
-                            ADDRTO = info?.EndPostion,
-                            STARTTIME = DateTime.Now,
-                            UPDATEUSER = "WCS",
-                            UPDATETIME = DateTime.Now,
-                            WMSTASK = int.Parse(info?.WMSTaskNum!),
-                            TaskGroupKey = info?.TaskGroupKey,
-                            ADDRNEXT = next.CODE,
-                            HEIGHT = dev.Data2.GoodsSize,
-                            AgvTask = agvTask?.ID ?? 0,
-                            FLOOR = 2
-                        };
-
-                        db.Default.Set<WCS_TASK>().Add(task);
-                        finishTaskList.Add(new FinishTaskList<int>(task.WMSTASK, item.Station));
-                    }
-                    //两个任务一起创建
-                    db.Default.SaveChanges();
-                });
-
-                //检查对应的任务是否已创建成功
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.WMSTASK == finishTask.FinishCode);
-                        if (task == null) continue;
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = task.ADDRFROM.ToShort();
-                        finishTask.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                        finishTask.Station.Data.Goodsnum = (short)finishTaskList.Count;
-                        finishTask.Station.Data.CmdType = IstationCmdType.扫码入库;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE is "G1386" or "G1435";
-        }
-    }
-
-    /// <summary>
-    /// 涂布入库分配巷道
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布入库分配巷道")]
-    public class 涂布入库分配巷道 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                const string key = $"WCS:Lock:CoatingAllocationTunnel";
-                try
-                {
-                    if (ProtocolProxy.YG150Redis.Get(key) != null) throw new WarnException($"[CoatingAllocationTunnel]--触发并发管控");
-                    ProtocolProxy.YG150Redis.Set(key, key);
-                    var code = stationDeviceGroup.Entity.CODE;
-                    //两个设备都必须满足的条件
-                    if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException("等待执行任务,凭证号不一致");
-                    if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行状态");
-
-                    //成功分配巷道的任务的任务
-                    var finishTaskList = new List<FinishTaskList<int>>();
-                    var devise = stationDeviceGroup.Items.Where(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Request == IstationRequest.请求分配目标地址)
-                                               .Where(v => v.Data2.Tasknum > 10000 && v.Data2.Goodsend != 0);
-                    var enumerable = devise as Device<IStation520, IStation521, IStation523>[] ?? devise.ToArray();
-                    if (!enumerable.Any()) return; //无可执行任务
-                    var taskIds = enumerable.Select(dev => dev.Data2.Tasknum).ToList();
-                    //变更数据库信息
-                    DB.Do(db =>
-                    {
-                        var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-
-                        taskList.ValidTaskCheck(enumerable.Count(), db);
-
-                        var res = WMS.GetTunnelList(taskList.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                        if (string.IsNullOrEmpty(res.TunnelNum)) throw new WarnException($"WMS未返回巷道");
-                        var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                        var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                        var tunnelInfos = new List<TunnelInfo>();
-                        foreach (var item in tunnels)
-                        {
-                            //当前巷道的取货点
-                            var allIn = Device.Where(v => v.Is(DF.SRM涂布取货)) //二楼所有取货点
-                                              .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
-                                              .Select(v => v.CODE)
-                                              .ToList();
-
-                            //下一个目标地址包含取货点的设备,此时获得的数据是旋转台
-                            var turntable = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && allIn.Contains(p.NEXT.CODE))).Select(v => v.CODE);
-                            //获得RGV的交货点
-                            var rgvDeliveryPoint = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && turntable.Contains(p.NEXT.CODE)))
-                                          .Select(v => v.Create<StationDevice>()) //取所有可以到达取货点设备的信息
-                                          .Where(v => !v.Data3.Status.HasFlag(StationStatus.运行状态位)
-                                                   && !v.Data2.Status.HasFlag(IstationStatus.光电状态)
-                                                   && v.Data2.Tasknum < 10000
-                                                   && v.Data3.Status.HasFlag(StationStatus.自动))//筛选出空闲的路径点,此处因输送机都是一个动力,因此可以先找路径点再找设备组
-                                          .Distinct()
-                                          .FirstOrDefault();//去一次重
-                            if (rgvDeliveryPoint == null) continue;
-                            var taskInStation = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => d.MEMBER == rgvDeliveryPoint.Entity)).MinBy(p => p.CODE);
-                            //只能有一组任务的下一个地址是交货点
-                            if (db.Default.Set<WCS_TASK>().Any(v => v.ADDRNEXT == taskInStation.CODE && v.STATUS < TaskStatus.已完成)) continue;
-
-                            //RGV是否有正在前往这个地址的任务
-                            var rgvList = Device.Where(v => v.Is(DF.涂布RGV)).Select(v => v.Create<RGVDevice>());
-                            if (rgvList.Any(v => (!v.Data2.SystemStatus.HasFlag(WCS.Entity.Protocol.RGV.RGVRunStatus.空闲) || !v.Data2.WorkMode.HasFlag(WCS.Entity.Protocol.RGV.RGVMode.自动))
-                                                && v.Data2.TaskType_1 == WCS.Entity.Protocol.RGV.RGVTaskType.放货
-                                                && v.Data2.DestPosition_1 == taskInStation?.CODE.Replace("G", "").ToShort())) continue;
-
-                            tunnelInfos.Add(new TunnelInfo
-                            {
-                                Tunnel = item,
-                                taskIN = taskInStation, //找到放货点设备所在组
-                                SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                            });
-                        }
-                        //筛选出优先级最高的可用巷道
-                        var tunnelInfo = tunnelInfos.Where(v => { try { return v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程; } catch { return false; } })
-                            .Where(v => !db.Default.Set<WCS_TASK>().Any(p => p.Priority > 0 && p.DEVICE == v.SRM.Entity.CODE && p.STATUS < TaskStatus.堆垛机完成)).MinBy(v => tunnelNo.IndexOf(v.Tunnel.CODE));
-                        if (tunnelInfo == null) throw new WarnException("无可用巷道");
-
-                        //开始变更任务信息
-                        foreach (var item in enumerable)
-                        {
-                            var dev = item.Entity.Create<StationDevice>();
-                            var task = taskList.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-                            if (task == null) throw new WarnException($"WCS无该任务{dev.Data2.Tasknum}--{dev.Entity.CODE}");
-
-                            task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                            task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                            task.ADDRNEXT = tunnelInfo.taskIN.CODE;
-                            task.TaskGroupKey = res.WMSTaskGroupKey;
-                            task.ADDRTO = task.DEVICE;
-                            task.CreateStatusLog(db, $"一次分配至堆垛机{task.DEVICE}", this.GetType());
-                            finishTaskList.Add(new FinishTaskList<int>(task.ID, dev));
-                        }
-                        db.Default.SaveChanges();
-                    });
-
-                    // 开始将任务信息写入到设备
-                    DB.Do(db =>
-                    {
-                        foreach (var finishTask in finishTaskList)
-                        {
-                            var task = db.Default.Set<WCS_TASK>().Find(finishTask.FinishCode);
-                            if (task == null) continue;
-
-                            finishTask.Station.Data.Tasknum = task.ID;
-                            finishTask.Station.Data.Goodsstart = stationDeviceGroup.Entity.CODE.Replace("G", "").ToShort();
-                            finishTask.Station.Data.Goodsend = task.ADDRNEXT.Replace("G", "").ToShort();
-                            finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                            finishTask.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                            finishTask.Station.Data.VoucherNo++;
-                        }
-                    });
-                }
-                finally
-                {
-                    ProtocolProxy.YG150Redis.Del(key);
-                }
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE is "G2" or "G3";
-        }
-    }
-
-    /// <summary>
-    /// 涂布入库旋转台二次分配巷道
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布入库旋转台二次分配巷道")]
-    public class 涂布入库旋转台二次分配巷道 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                var code = stationDeviceGroup.Entity.CODE;
-
-                //两个设备都必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException("等待执行任务--凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-                //成功分配巷道的任务的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-                var devise = stationDeviceGroup.Items.Where(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Request == IstationRequest.请求分配目标地址)
-                                          .Where(v => v.Data2.Tasknum > 10000);
-                var enumerable = devise as Device<IStation520, IStation521, IStation523>[] ?? devise.ToArray();
-                if (!enumerable.Any()) return; //无可执行任务
-                var taskIds = enumerable.Select(dev => dev.Data2.Tasknum).ToList();
-                //变更数据库信息
-                DB.Do(db =>
-                {
-                    var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-
-                    taskList.ValidTaskCheck(enumerable.Count(), db);
-
-                    if (taskList.Any(v => v.TYPE == TaskType.倒库))
-                    {
-                        foreach (var item in taskList)
-                        {
-                            var dev = enumerable.FirstOrDefault(v => v.Data2.Tasknum == item.ID).Entity.Create<StationDevice>();
-                            finishTaskList.Add(new FinishTaskList<int>(item.ID, dev));
-                        }
-                    }
-                    else
-                    {
-                        var res = WMS.GetTunnelList(taskList.Select(v => v.WMSTASK.ToString()).ToList(), code);
-                        if (string.IsNullOrEmpty(res.TunnelNum)) throw new WarnException($"WMS未返回巷道");
-                        var tunnelNo = res.TunnelNum.Split(',').Select(v => "TY" + v).ToList();
-
-                        var tunnels = Device.Where(v => tunnelNo.Contains(v.CODE)).ToList();
-
-                        var tunnelInfos = new List<TunnelInfo>();
-                        foreach (var item in tunnels)
-                        {
-                            //当前巷道的取货点
-                            var allIn = Device.Where(v => v.Is(DF.SRM涂布取货)) //一楼所有取货点
-                                              .Where(v => v.ROUTES.Any(p => p.NEXT == item)) //下一个点为当前巷道的取货点
-                                              .Select(v => v.CODE)
-                                              .ToList();
-                            //下一个目标地址包含取货点的设备,此时获得的数据是旋转台
-                            var turntable = Device.Where(v => v.IsConv() && v.ROUTES.Any(p => p.NEXT != null && allIn.Contains(p.NEXT.CODE)))
-                                                  .Where(v => stationDeviceGroup.Items.Any(p => p.Entity == v))// 筛选出包含在当前设备组的设备
-                                                  .Distinct()
-                                                  .FirstOrDefault();//去一次重
-                            if (turntable == null) continue;
-                            var dev = Device.Where(p => p.CODE.StartsWith("G") && p.DEVICEGROUP.Any(d => d.MEMBER == turntable)).MinBy(p => p.CODE);
-
-                            tunnelInfos.Add(new TunnelInfo
-                            {
-                                Tunnel = item,
-                                taskIN = dev, //找到放货点设备所在组
-                                SRM = Device.Where(p => p.IsSC()).FirstOrDefault(p => item.ROUTES.Any(d => d.NEXT.CODE == p.CODE)).Create<SRMDevice>()
-                            });
-                        }
-                        //筛选出优先级最高的可用巷道
-                        var tunnelInfo = tunnelInfos.Where(v => { try { return v.SRM.Data3.SCAlarm == 0 && v.SRM.Data2.SRMMode == SCMode.远程; } catch { return false; } }).MinBy(v => tunnelNo.IndexOf(v.Tunnel.CODE));
-                        if (tunnelInfo == null) throw new WarnException("无可用巷道");
-
-                        //开始变更任务信息
-                        foreach (var item in enumerable)
-                        {
-                            var dev = item.Entity.Create<StationDevice>();
-                            var task = taskList.FirstOrDefault(p => p.ID == dev.Data2.Tasknum);
-
-                            if (task == null) throw new WarnException($"WCS无该任务{dev.Data2.Tasknum}--{dev.Entity.CODE}");
-
-                            task.DEVICE = tunnelInfo.SRM.Entity.CODE;
-                            task.TUNNEL = tunnelInfo.Tunnel.CODE;
-                            task.ADDRNEXT = dev.Entity.GetPath(task.DEVICE).CODE;
-                            task.TaskGroupKey = res.WMSTaskGroupKey;
-                            task.ADDRTO = task.DEVICE;
-
-                            task.CreateStatusLog(db, $"二次分配至堆垛机{task.DEVICE}", this.GetType());
-                            finishTaskList.Add(new FinishTaskList<int>(task.ID, dev));
-                        }
-                        db.Default.SaveChanges();
-                    }
-                });
-
-                // 开始将任务信息写入到设备
-                DB.Do(db =>
-                {
-                    foreach (var finishTask in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().Find(finishTask.FinishCode);
-                        if (task == null) continue;
-
-                        finishTask.Station.Data.Tasknum = task.ID;
-                        finishTask.Station.Data.Goodsstart = stationDeviceGroup.Entity.CODE.Replace("G", "").ToShort();
-                        if (task.TYPE == TaskType.倒库)
-                        {
-                            finishTask.Station.Data.Goodsend = finishTask.Station.Entity.GetPath(task.DEVICEDL).CODE.ToShort();
-                        }
-                        else
-                        {
-                            finishTask.Station.Data.Goodsend = finishTask.Station.Entity.GetPath(task.DEVICE).CODE.ToShort();
-                        }
-                        finishTask.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finishTask.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        finishTask.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return _devCodes.Contains(dev.CODE);
-        }
-
-        private readonly List<string> _devCodes = new()
-        {
-            "G1404",
-            "G1413",
-            "G1420",
-            "G1429",
-        };
-    }
-}

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

@@ -1,625 +0,0 @@
-using DBHelper;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using WCS.Core;
-using WCS.Entity;
-using WCS.Entity.Protocol;
-using WCS.Service.Entity;
-using WCS.Service.Extensions;
-using WCS.Service.Handlers;
-using WCS.Service.Helpers;
-using WCS.Service.Log;
-
-namespace WCS.Service.Works.Station
-{
-    /// <summary>
-    /// 涂布堆垛机放货分配目标地址
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布堆垛机放货分配目标地址")]
-    public class 涂布堆垛机放货分配目标地址 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException($"等待执行任务,凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-
-                var devise = new List<FinishTaskList<string>>();
-                foreach (var dev in stationDeviceGroup.Items)
-                {
-                    //没有请求
-                    if (dev.Data2.Request != IstationRequest.堆垛机放货完成请求目标地址)
-                    {
-                        InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}无请求-堆垛机放货完成请求--4");
-                        continue;
-                    }
-                    //没有光电
-                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    };
-                    devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                }
-
-                //成功处理的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                DB.Do(db =>
-                {
-                    foreach (var dev in devise)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => (v.TYPE == TaskType.出库 || v.TYPE == TaskType.倒库) && v.SRMSTATION == dev.FinishCode && v.STATUS == TaskStatus.堆垛机完成) ?? throw new WarnException("无任务");
-                        var tasks = db.Default.Set<WCS_TASK>().Where(v => v.TaskGroupKey == task.TaskGroupKey);
-                        if (tasks.Any(v => v.STATUS != TaskStatus.堆垛机完成 && v.STATUS != TaskStatus.执行中)) throw new WarnException("任务异常,同组任务状态不为堆垛机完成或执行中");
-
-                        task.STATUS = TaskStatus.执行中;
-                        task.CreateStatusLog(db, $"堆垛机放货点分配目标地址{task.ADDRNEXT}", this.GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, dev.Station));
-                    }
-                    db.Default.SaveChanges();
-                });
-
-                DB.Do(db =>
-                {
-                    foreach (var finish in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == finish.FinishCode);
-                        if (task == null) continue;
-                        finish.Station.Data.Tasknum = task.ID;
-                        finish.Station.Data.Goodsstart = finish.Station.Entity.CODE.ToShort();
-                        finish.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                        finish.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finish.Station.Data.CmdType = IstationCmdType.堆垛机放货完成请求目标地址;
-                        finish.Station.Data.VoucherNo++;
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return _devCodes.Contains(dev.CODE);
-        }
-
-        private readonly List<string> _devCodes = new() { "G1283", "G1290", "G1292", "G1299", "G1301", "G1308", "G1310" };
-    }
-
-    /// <summary>
-    /// 涂布出库分配出库口
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布出库分配出库口")]
-    public class 涂布出库分配出库口 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                const string key = $"WCS:Lock:CoatingAllocationOutboundDeliveryPoint";
-                try
-                {
-                    if (ProtocolProxy.YG150Redis.Get(key) != null) return; //并发管控
-                    ProtocolProxy.YG150Redis.Set(key, key);
-                    if (stationDeviceGroup.Items.Any(v => v.Data.VoucherNo != v.Data2.VoucherNo)) throw new WarnException("等待执行任务,凭证号不一致");
-                    if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("运行中");
-                    var devise = new List<FinishTaskList<string>>();
-                    foreach (var dev in stationDeviceGroup.Items)
-                    {
-                        if (dev.Data2.Request != IstationRequest.请求分配目标地址)
-                        {
-                            InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}无请求-分配目标地址--2");
-                            continue;
-                        }
-                        if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                        {
-                            InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                            continue;
-                        }
-                        if (dev.Data2.Tasknum < 10000)
-                        {
-                            InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求有光电无任务", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                            continue;
-                        }
-                        devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                    }
-                    if (!devise.Any()) return;
-
-                    var finishTaskList = new List<FinishTaskList<int>>();
-                    const string key1 = $"WCS:Lock:FirstOut";
-                    DB.Do(db =>
-                    {
-                        #region 开始进行优先判断
-
-                        string value = ProtocolProxy.YG150Redis.Get(key1);
-                        //当前被锁定的不是当前设备
-                        if (value != key1 && value != obj.Entity.CODE) return;
-                        ProtocolProxy.YG150Redis.Set(key1, obj.Entity.CODE); //锁定当前设备,输送线是不是并行执行,所以不用增加redis事务锁
-
-                        #endregion 开始进行优先判断
-                        //验证总数
-                        if (db.Default.Set<WCS_TASK>().Count(v => v.STATUS < TaskStatus.已完成 && v.ADDRNEXT == "G1") >= 3) throw new WarnException("总数已达3,流量管控");
-
-
-
-                        foreach (var dev in devise)
-                        {
-                            var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == dev.Station.Data2.Tasknum) ?? throw new WarnException("无任务");
-                            var tasks = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey);
-                            if (tasks != devise.Count) throw new WarnException($"可执行任务数{devise.Count},实际任务数{tasks}");
-
-                            //找到下两个地址
-                            if (task.TYPE == TaskType.倒库)
-                            {
-                                var next1 = dev.Station.Entity.GetNext(task.TUNNELDL);
-                                var next3 = Device.Where(v => v.IsDevGroup()).FirstOrDefault(v => v.DEVICEGROUP.Any(p => p.MEMBER.CODE == next1.CODE));
-                                task.ADDRNEXT = next3.CODE;
-                            }
-                            else
-                            {
-                                task.ADDRNEXT = "G1";
-                            }
-                            task.CreateStatusLog(db, $"涂布出库分配出库口{task.ADDRNEXT}", this.GetType());
-                            finishTaskList.Add(new FinishTaskList<int>(task.ID, dev.Station));
-                        }
-                        db.Default.SaveChanges();
-                    });
-
-                    DB.Do(db =>
-                    {
-                        foreach (var finish in finishTaskList)
-                        {
-                            var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == finish.FinishCode);
-                            if (task == null) continue;
-                            finish.Station.Data.Tasknum = task.ID;
-                            finish.Station.Data.Goodsstart = finish.Station.Entity.CODE.ToShort();
-                            finish.Station.Data.Goodsend = task.ADDRNEXT.Replace("G", "").ToShort();
-                            finish.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                            finish.Station.Data.GoodsSize = task.Length.ToShort();
-                            finish.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                            finish.Station.Data.VoucherNo++;
-
-                            #region 结束锁定
-
-                            string value = ProtocolProxy.YG150Redis.Get(key1);
-                            //当前设备任然被锁定
-                            if (value == obj.Entity.CODE)
-                            {
-                                ProtocolProxy.YG150Redis.Set(key1, key1);
-                            };
-
-                            #endregion 结束锁定
-                        }
-                    });
-                }
-                finally
-                {
-                    ProtocolProxy.YG150Redis.Del(key);
-                }
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return _devCodes.Contains(dev.CODE);
-        }
-
-        private readonly List<string> _devCodes = new() { "G5", "G7", "G9", "G11" };
-    }
-
-    /// <summary>
-    /// 涂布出库分配AGV取货点
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布出库分配AGV取货点")]
-    public class 涂布出库分配AGV取货点 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                //必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data2.VoucherNo != v.Data.VoucherNo)) throw new WarnException("凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("设备运行中");
-
-                var devise = new List<FinishTaskList<string>>();
-
-                //获取需要执行的设备信息
-                foreach (var dev in stationDeviceGroup.Items)
-                {
-                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                    {
-                        InfoLog.INFO_INFO($"{dev.Entity.CODE}--没有光电");
-                        continue;
-                    }
-                    if (dev.Data2.Request != IstationRequest.请求分配目标地址)
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}--有光电没有分配目标地址请求--2", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    };
-                    if (dev.Data2.Tasknum < 10000)
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}--有光电有请求没有任务号", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    }
-
-                    devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                }
-
-                if (!devise.Any()) return; //无可执行任务
-                //验证可执行任务数与有效任务数是否一致
-                var taskIds = devise.Select(dev => dev.Station.Data2.Tasknum).ToList();
-
-                //成功处理的任务
-                var finishTaskList = new List<FinishTaskList<int>>();
-
-                DB.Do(db =>
-                {
-                    var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-
-                    var task1 = taskList.FirstOrDefault();
-                    var taskCount = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == task1.TaskGroupKey && v.TYPE == TaskType.出库);
-                    //开始检查任务数是否匹配
-                    if (devise.Count != taskCount) throw new WarnException($"可执行数{devise.Count},任务组任务数{taskCount},数量不匹配,{task1?.ID}-{task1?.TaskGroupKey}");
-
-                    var stationList = new List<FinishTaskList<WCS_TASK>>();
-
-                    var G1340 = Device.Find("1340", "1341").Select(v => v.Create<StationDevice>());
-                    var G1343 = Device.Find("1343", "1344").Select(v => v.Create<StationDevice>());
-                    List<StationDevice> station = new List<StationDevice>();
-                    if (G1340.Any(v => v.Data3.Status.HasFlag(StationStatus.自动)
-                              && !v.Data3.Status.HasFlag(StationStatus.运行状态位)
-                              && !v.Data3.Status.HasFlag(StationStatus.有货状态位)
-                              && !v.Data2.Status.HasFlag(IstationStatus.光电状态)
-                              && v.Data2.Tasknum < 10000))
-                    {
-                        station.AddRange(G1340);
-                    }
-                    else if (G1343.Any(v => v.Data3.Status.HasFlag(StationStatus.自动)
-                              && !v.Data3.Status.HasFlag(StationStatus.运行状态位)
-                              && !v.Data3.Status.HasFlag(StationStatus.有货状态位)
-                              && !v.Data2.Status.HasFlag(IstationStatus.光电状态)
-                              && v.Data2.Tasknum < 10000))
-                    {
-                        station.AddRange(G1343);
-                    }
-
-                    //先判断1340是否可以放货
-                    foreach (var dev in devise)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == dev.Station.Data2.Tasknum) ?? throw new WarnException($"WCS无[{dev.Station.Data2.Tasknum}]任务信息");
-                        var addNext = "";
-                        switch (dev.Station.Entity.CODE)
-                        {
-                            case "1337":
-                                {
-                                    var station1343 = Device.Find("1343").Create<StationDevice>();
-                                    addNext = station.OrderBy(v => v.Entity.CODE).FirstOrDefault().Entity.CODE;
-
-                                    break;
-                                }
-                            case "1338":
-                                {
-                                    var station1344 = Device.Find("1344").Create<StationDevice>();
-                                    addNext = station.OrderByDescending(v => v.Entity.CODE).FirstOrDefault().Entity.CODE;
-                                    break;
-                                }
-                        }
-
-                        task.ADDRNEXT = addNext;
-                        task.CreateStatusLog(db, $"涂布出库分配AGV取货点{addNext}", this.GetType());
-                        finishTaskList.Add(new FinishTaskList<int>(task.ID, dev.Station.Entity.Create<StationDevice>()));
-                        stationList.Add(new FinishTaskList<WCS_TASK>(task, dev.Station.Entity.Create<StationDevice>()));
-                    }
-
-                    #region 校验两个地址是否一致
-
-                    if (stationList.Count == 2)
-                    {
-                        stationList = stationList.OrderBy(v => v.FinishCode.ADDRNEXT.ToShort()).ToList();
-                        var task3 = stationList[0];
-                        var task4 = stationList[1];
-                        switch (task3.FinishCode.ADDRNEXT)
-                        {
-                            case "1343" when task4.FinishCode.ADDRNEXT == "1344":
-                                break;
-
-                            case "1340" when task4.FinishCode.ADDRNEXT == "1341":
-                                break;
-
-                            default:
-                                {
-                                    var devise1 = stationList.Select(v => v.Station);
-                                    foreach (var dev in devise1)                                                    
-                                    {
-                                        if (!dev.Data3.Status.HasFlag(StationStatus.自动)) throw new WarnException($"{dev.Entity.CODE}--不是自动");
-                                        if (dev.Data2.Tasknum > 10000) throw new WarnException($"{dev.Entity.CODE}--已有任务");
-                                    }
-
-                                    break;
-                                }
-                        }
-                    }
-
-                    #endregion 校验两个地址是否一致
-
-                    db.Default.SaveChanges();
-                });
-
-                DB.Do(db =>
-                {
-                    foreach (var finish in finishTaskList)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == finish.FinishCode) ?? throw new WarnException($"已完成DB任务变更,但写入PLC信息是找不到任务{finish.FinishCode}");
-
-                        finish.Station.Data.Tasknum = task.ID;
-                        finish.Station.Data.Goodsstart = finish.Station.Entity.CODE.ToShort();
-                        finish.Station.Data.Goodsend = task.ADDRNEXT.ToShort();
-                        finish.Station.Data.GoodsSize = task.Length.ToShort();
-                        finish.Station.Data.Goodsnum = finishTaskList.Count.ToShort();
-                        finish.Station.Data.CmdType = IstationCmdType.分配目标地址;
-                        finish.Station.Data.VoucherNo++;
-                        InfoLog.INFO_AGV($"出库分配AGV取货点[{finish.FinishCode}]-[{finish.Station.Data.Goodsend}]");
-                    }
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1337";
-        }
-    }
-
-    /// <summary>
-    /// 涂布出库返回任务长度
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布出库返回任务长度")]
-    public class 涂布出库返回任务长度 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-            {
-                //必须满足的条件
-                if (stationDeviceGroup.Items.Any(v => v.Data2.VoucherNo != v.Data.VoucherNo)) throw new WarnException("凭证号不一致");
-                if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new DoException("设备运行中");
-
-                var devise = new List<FinishTaskList<string>>();
-
-                //获取需要执行的设备信息
-                foreach (var dev in stationDeviceGroup.Items)
-                {
-                    if (dev.Data2.Request != IstationRequest.请求分配目标地址)
-                    {
-                        InfoLog.INFO_INFO($"{stationDeviceGroup.Entity.CODE}无请求-分配目标地址--2");
-                        continue;
-                    }
-                    if (!dev.Data2.Status.HasFlag(IstationStatus.光电状态))
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求无光电", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    }
-                    if (dev.Data2.Tasknum < 10000)
-                    {
-                        InfoLog.INFO_WarnDb($"{dev.Entity.CODE}有请求有光电无任务", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                        continue;
-                    }
-                    devise.Add(new FinishTaskList<string>(dev.Entity.CODE, dev.Entity.Create<StationDevice>()));
-                }
-
-                if (!devise.Any()) return;//无可执行任务
-                                          //验证可执行任务数与有效任务数是否一致
-                var taskIds = devise.Select(dev => dev.Station.Data2.Tasknum).ToList();
-
-                DB.Do(db =>
-                {
-                    var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
-                    var taskCount = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == taskList.FirstOrDefault().TaskGroupKey && v.TYPE == TaskType.出库);
-
-                    if (devise.Count != taskCount) throw new WarnException($"可执行数{devise.Count},任务组任务数{taskCount},数量不匹配");
-
-                    //开始处理需要分配目标地址的设备
-                    foreach (var dev in devise)
-                    {
-                        var task = db.Default.Set<WCS_TASK>().Find(dev.Station.Data2.Tasknum);
-                        if (task == null) throw new WarnException("WCS无该任务信息");
-                        task.ADDRNEXT = "G1340";
-                        dev.Station.Data.GoodsSize = task.Length.ToShort();
-                        dev.Station.Data.VoucherNo++;
-                    }
-                    db.Default.SaveChanges();
-                });
-            });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1334";
-        }
-    }
-
-    /// <summary>
-    /// 涂布叫料
-    /// </summary>
-    [WorkTitle(typeof(CoatingHandler), "涂布叫料")]
-    public class 涂布叫料 : Work<StationDeviceGroup>
-    {
-        protected override void Do(StationDeviceGroup obj)
-        {
-            obj.EX(stationDeviceGroup =>
-             {
-                 #region 处理新增叫料任务
-
-                 DB.Do(db =>
-                 {
-                     //找到所有的AGV任务
-                     var agvTasks = db.Default.Set<WCS_AGVTask>().Where(v => v.TaskType == AGVTaskType.叫料)
-                     .Where(v => v.Status < AGVTaskStatus.完成).ToArray();
-
-                     foreach (var tasking in agvTasks)
-                     {
-                         var position = tasking.Position;
-                         if (!ProtocolProxy.AllDatas.ContainsKey(position))
-                             ProtocolProxy.AllDatas[position] = new ProdLineData();
-                         var pld = ProtocolProxy.AllDatas[position] as ProdLineData;
-                         pld!.Frame = LogicHandler.Frame;
-                         pld.Code = position;
-                         pld.TaskList.Add(tasking);
-
-                         if (tasking.Status == AGVTaskStatus.新建)
-                         {
-                             if (stationDeviceGroup.Entity.CODE != "G1340") continue;
-                             var qty = db.Default.Set<WCS_AGVTask>().Where(v => v.TaskType == AGVTaskType.叫料 && v.Status > AGVTaskStatus.新建 && v.Status < AGVTaskStatus.完成).Count(v => v.Position == tasking.Position);
-
-                             var cmQty = ProtocolProxy.YGWMS150Redis.Get("MaxLineCallTaskCount").ToInt();
-
-                             if (qty >= cmQty)
-                             {
-                                 InfoLog.INFO_WarnDb($"{tasking.Position}正在执行的叫料任务数量已达{qty},暂停出库", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常);
-                                 continue;
-                             };
-
-                             //涂布叫料默认目标地址G1340,到达G1340后再决定是否要继续前进一步
-                             List<I_WCS_GetOutTaskResponseSingle> res;
-                             try
-                             {
-                                 res = WMS.GetOutTask(tasking.Position.Replace("_OUT", ""), "G1340");
-                             }
-                             catch (WarnException ex)
-                             {
-                                 InfoLog.INFO_WarnDb($"{ex.Message}", stationDeviceGroup.Entity.CODE, WCS_EXCEPTIONTYPE.设备异常);
-                                 continue;
-                             };
-
-                             res.ForEach(outTask =>
-                             {
-                                 var srm = Device.Find(outTask.TunnelNum).ROUTES.Where(v => v.NEXT.IsSC()).Select(v => v.NEXT).FirstOrDefault();
-
-                                 var loc = $"{outTask.Row}-{outTask.Colomn}-{outTask.Layer}";
-
-                                 var task = new WCS_TASK
-                                 {
-                                     TYPE = TaskType.出库,
-                                     STATUS = WCS.Entity.TaskStatus.新建,
-                                     ADDRFROM = loc,
-                                     ADDRTO = "G1340",
-                                     BARCODE = outTask.ContainerBarCode,
-                                     TUNNEL = outTask.TunnelNum,
-                                     WMSTASK = int.Parse(outTask.WMSTaskNum),
-                                     UPDATEUSER = "WCS",
-                                     SRMSTATION = "",
-                                     DEVICE = srm?.CODE,
-                                     AgvTask = tasking.ID,
-                                     Length = outTask.Length,
-                                     FLOOR = 2
-                                 };
-                                 task.TaskGetSrmStation();
-                                 task.CreateStatusLog(db, $"创建任务", this.GetType());
-                                 db.Default.Set<WCS_TASK>().Add(task);
-                                 tasking.Status = AGVTaskStatus.确认;
-                                 tasking.UpdateTime = DateTime.Now;
-                                 db.Default.SaveChanges();
-                                 tasking.AGVStatusChange(AGVTaskStatus.确认, "获取出库任务");
-                             });
-                         }
-                         else if (tasking.AGVStatus == AGVTaskStatus.完成)
-                         {
-                             tasking.Status = tasking.AGVStatus;
-                             tasking.UpdateTime = DateTime.Now;
-                             db.Default.SaveChanges();
-                             tasking.AGVStatusChange(tasking.AGVStatus, "完成任务");
-                         }
-                         else if (tasking.AGVStatus == AGVTaskStatus.取消)
-                         {
-                             tasking.Status = tasking.AGVStatus;
-                             tasking.UpdateTime = DateTime.Now;
-                             db.Default.SaveChanges();
-                             tasking.AGVStatusChange(tasking.AGVStatus, "取消任务");
-                         }
-                     }
-                 });
-
-                 #endregion 处理新增叫料任务
-
-                 //空闲自动,停止运行
-                 if (stationDeviceGroup.Items.Any(v => v.Data2.VoucherNo != v.Data.VoucherNo)) throw new WarnException("等待执行任务");
-                 if (stationDeviceGroup.Items.Any(v => !v.Data3.Status.HasFlag(StationStatus.自动))) return;
-                 if (stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) throw new WarnException("设备运行中");
-
-                 var taskIds = new List<int>();
-                 stationDeviceGroup.Items.ToList().ForEach(dev => taskIds.Add(dev.Data2.Tasknum));
-                 DB.Do(db =>
-                 {
-                     var taskList = db.Default.Set<WCS_TASK>().Where(v => taskIds.Contains(v.ID));
-                     if (!taskList.Any()) return;
-                     if (taskList == null) throw new WarnException($"WCS任务号{JsonConvert.SerializeObject(taskIds)}不存在");
-                     if (taskList.Any(v => v.TYPE != TaskType.出库)) throw new WarnException("有任务的类型不是出库");
-                     if (taskList.Any(v => v.AgvTask == 0)) throw new WarnException("人工出库任务,请手动搬走");
-
-                     var agvtask = db.Default.Set<WCS_AGVTask>().Find(taskList.FirstOrDefault().AgvTask);
-                     if (agvtask == null) throw new WarnException($"AGV任务号{taskList.FirstOrDefault().AgvTask}不存在");
-                     if (taskList.Count() != db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == taskList.FirstOrDefault().TaskGroupKey && v.TYPE == TaskType.出库)) throw new WarnException("可执行任务数与实际任务数不符");
-
-                     if (agvtask.Status == AGVTaskStatus.确认)
-                     {
-                         if (!stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.高位))) throw new WarnException("不在高位");
-                         var flag = db.Default.Set<WCS_AGVTask>()
-                             .Where(v => v.TaskType == AGVTaskType.叫料).Count(v => v.Status > AGVTaskStatus.确认 && v.Status < AGVTaskStatus.取放完成);
-                         if (flag >= 2) throw new Exception("有2未完成的AGV出库任务");
-
-                         taskList.ToList().ForEach(task =>
-                                 {
-                                     task.STATUS = WCS.Entity.TaskStatus.已完成;
-                                     task.UPDATETIME = DateTime.Now;
-                                     task.ENDTIME = DateTime.Now;
-                                 });
-
-                         agvtask.Station = stationDeviceGroup.Entity.CODE;
-                         agvtask.Status = AGVTaskStatus.执行;
-                         agvtask.UpdateTime = DateTime.Now;
-                         db.Default.SaveChanges();
-                         agvtask.AGVStatusChange(AGVTaskStatus.执行, "分配取货点");
-                     }
-                     else if (agvtask.Status < agvtask.AGVStatus)
-                     {
-                         if (agvtask.AGVStatus == AGVTaskStatus.请求_允许)
-                         {
-                             if (!stationDeviceGroup.Items.Any(v => v.Data3.Status.HasFlag(StationStatus.高位))) throw new WarnException("不在高位");
-                             if (agvtask.Status < AGVTaskStatus.执行) throw new WarnException($"AGV状态错误-{agvtask.Status}");
-                             if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.AGV取货完成信号))) throw new WarnException("任务清零信号未清除");
-                             if (!stationDeviceGroup.Items.Any(v => v.Data2.Tasknum > 10000 && v.Data2.Status.HasFlag(IstationStatus.光电状态))) throw new DoException("没有设备有任务且有光电");
-
-                             agvtask.Status = agvtask.AGVStatus;
-                             agvtask.UpdateTime = DateTime.Now;
-                             db.Default.SaveChanges();
-                             agvtask.AGVStatusChange(agvtask.AGVStatus, "允许取货");
-                         }
-                         else if (agvtask.AGVStatus == AGVTaskStatus.取放完成)
-                         {
-                             if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.AGV取货完成信号))) throw new WarnException("任务清零信号未清除");
-                             if (stationDeviceGroup.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态))) throw new WarnException("AGV取货完成后依然有光电信号");
-                             if (agvtask.Status < AGVTaskStatus.请求_允许) throw new WarnException("AGV任务状态有误");
-
-                             agvtask.Status = agvtask.AGVStatus;
-                             agvtask.UpdateTime = DateTime.Now;
-                             db.Default.SaveChanges();
-                             agvtask.AGVStatusChange(agvtask.AGVStatus, "允许设备下降顶升");
-
-                             foreach (var dev in stationDeviceGroup.Items)
-                             {
-                                 dev.Data.Istation521Status = IstationStatus.AGV取货完成信号;
-                             }
-                         }
-                     }
-                 });
-             });
-        }
-
-        protected override bool SelectDevice(WCS_DEVICE dev)
-        {
-            return dev.CODE == "G1340" || dev.CODE == "G1343";
-        }
-    }
-}

+ 1 - 65
WCS.Core/LogicHandler.cs

@@ -107,70 +107,6 @@ namespace WCS.Core
                 Console.ResetColor();
                 last = DateTime.Now;
 
-                //Configs.DoCmds(cmd =>
-                //{
-                //    try
-                //    {
-                //        if (!cmd.ENABLED)
-                //            return;
-
-                //        var obj = Device.Find(cmd.DEVICE_CODE).PROTOCOLS.Where(v => v.DB.PROTOCOL == cmd.PROTOCOL).FirstOrDefault();
-                //        //var obj = AllObjects.OfType<WCS_DEVICEPROTOCOL>().Where(v => v.DB.PROTOCOL == cmd.PROTOCOL && v.DEVICE.CODE == cmd.DEVICE_CODE).FirstOrDefault();
-                //        if (obj != null)
-                //        {
-                //            var proxy = obj.Data() as ProtocolProxyBase;
-                //            if (proxy.WCSVersion != cmd.WCSVERSION && cmd.WCSVERSION >= 0)
-                //            {
-                //                throw new Exception("WCS数据已变更,无法执行CMD。ID:" + cmd.ID);
-                //            }
-                //            var prop = proxy.GetType().GetProperty(cmd.PROPERTY);
-                //            if (prop.PropertyType.IsEnum)
-                //            {
-                //                var value = Enum.Parse(prop.PropertyType, cmd.VALUE);
-                //                proxy.Update(cmd.PROPERTY, value, cmd.UPDATEUSER);
-                //            }
-                //            else
-                //            {
-                //                var value = Convert.ChangeType(cmd.VALUE, prop.PropertyType);
-                //                proxy.Update(cmd.PROPERTY, value, cmd.UPDATEUSER);
-                //            }
-                //        }
-                //    }
-                //    catch (Exception ex)
-                //    {
-                //        Console.WriteLine(ex.Message);
-                //    }
-                //});
-
-                Parallel.ForEach<LogicHandler>(Handlers, m =>
-                {
-                    var dm = DateTime.Now;
-                    try
-                    {
-                        m.Update(total);
-                    }
-                    catch (Exception ex)
-                    {
-                        //Console.WriteLine(ex.GetBaseException().Message);
-                    }
-                    var dm2 = (DateTime.Now - dm).TotalMilliseconds;
-                    //Console.WriteLine(m.GetType().Name + ":" + dm2);
-                });
-
-                //foreach (var m in Handlers)
-                //{
-                //    var dm = DateTime.Now;
-                //    try
-                //    {
-                //        m.Update(total);
-                //    }
-                //    catch (Exception ex)
-                //    {
-                //        //Console.WriteLine(ex.GetBaseException().Message);
-                //    }
-                //    var dm2 = (DateTime.Now - dm).TotalMilliseconds;
-                //}
-
                 Configs.Publish();
                 logicTimes = (int)(DateTime.Now - last).TotalMilliseconds;
             }
@@ -559,4 +495,4 @@ namespace WCS.Core
             return res;
         }
     }
-}
+}