using System; using System.Collections.Generic; using System.Linq; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol; using WCS.Service.Helpers; namespace WCS.Service.Extensions { /// /// 输送机设备组 /// public class StationDeviceGroup : DeviceGroup { private List RGVs; public StationDeviceGroup(WCS_DEVICE entity) : base(entity) { } /// /// 设备组是否满足任务执行条件 /// /// 给当前设备组下发任务时需要的请求 /// true:不满足执行条件需要进行停止执行 false:表示满足条件不需要停止执行 /// public bool WhetherToExecute(IstationRequest type = IstationRequest.无) { //当前组有一个运行的设备就停止执行 if (Items.Any(v => v.Data3.Status.HasFlag(StationStatus.运行状态位))) return true; //设备组中没有设备有光带信息 if (!Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态))) return true; ////有光电无任务 //if (Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000)) // throw new Exception(LogHelper.SpliceLogMessage("有光电无任务", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常)); ////有光电有任务无请求 //if (Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum < 10000 && (type != IstationRequest.无 && v.Data2.Request != type))) // throw new Exception(LogHelper.SpliceLogMessage($"有光电有任务无 {type} 请求", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常)); return false; } /// /// 获取设备组中需要取货的设备 /// /// /// public List> 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; } /// /// 获取设备组中需要分配目标地址的设备 /// /// /// public List> TaskedDeviceGetNextAddress() { var a = Items.Where(v => v.Data2.Status.HasFlag(IstationStatus.光电状态) && v.Data2.Tasknum > 10000) .Where(v => v.Data2.Goodsend.ToString() == v.Entity.CODE && v.Data2.Goodsend != 0) .ToList(); return a.Count == 0 ? null : a; } public float Position { get; } public float Length { get; } public RGVDevice NextRGV() { return new RGVDevice(new WCS_DEVICE()); } public float Distance(RGVDevice rgv) { return Math.Abs((Position - rgv.Position + Length) % Length); } public RGVDevice CurrentRGV() { return new RGVDevice(new WCS_DEVICE()); } /// /// /// /// public bool NeedRgv() { return true; } } /// /// 输送机设备 /// public class StationDevice : Device { public StationDevice(WCS_DEVICE entity) : base(entity) { } /// /// 设备组是否满足任务执行条件 /// /// 给当前设备组下发任务时需要的请求 /// true:不满足执行条件需要进行停止执行 false:表示满足条件不需要停止执行 /// public bool WhetherToExecute(IstationRequest type = IstationRequest.无) { //正在运行 if (Data3.Status.HasFlag(StationStatus.运行状态位)) return true; //上一次的任务还未执行 if (Data.VoucherNo != Data2.VoucherNo) throw new Exception(LogHelper.SpliceLogMessage($"等待任务[{Data2.Tasknum}]执行", Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常)); //没有光电 if (!Data2.Status.HasFlag(IstationStatus.光电状态)) return true; //没有任务号 switch (type) { case IstationRequest.无: if (Data2.Tasknum > 10000) throw new Exception(LogHelper.SpliceLogMessage($"设备已有任务任务", Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常)); break; case IstationRequest.扫码入库: if (Data2.Tasknum > 10000) throw new Exception(LogHelper.SpliceLogMessage($"设备已有任务任务", Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常)); break; case IstationRequest.堆垛机放货完成请求目标地址: if (Data2.Tasknum < 10000) throw new Exception(LogHelper.SpliceLogMessage($"设备无任务信息", Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常)); break; case IstationRequest.请求分配目标地址: if (Data2.Tasknum < 10000) throw new Exception(LogHelper.SpliceLogMessage($"设备无任务信息", Entity.CODE, WCS_EXCEPTIONTYPE.逻辑异常)); break; } //没有请求 if (type != IstationRequest.无 && Data2.Request != type) throw new Exception(LogHelper.SpliceLogMessage($"有光电有任务无 {type}", Entity.CODE, WCS_EXCEPTIONTYPE.设备异常)); return false; } } /// /// RGV设备 /// public class RGVDevice : Device { //需要记录每一个站台的位置 /// /// 涂布环穿 位置配置 /// private static List Coating = new List(); /// /// 拉膜环穿 位置配置 /// private static List PullFilm = new List(); public float Position { get { return Data2.Position; } } private static List AllRGVList { get; set; } static RGVDevice() { AllRGVList = Device.Where(v => v.IsRGV() && v.CODE != "RGV8").Select(v => v.Create()).ToList(); } public float Length { get; } public List RGVList { get { return AllRGVList.Where(v => v.Entity.PROTOCOLS.Any(d => Entity.PROTOCOLS.Any(e => e.DB.ID == d.DB.ID))) .Where(v => v.Entity.CODE != Entity.CODE).ToList(); } } public RGVDevice(WCS_DEVICE entity) : base(entity) { } /// /// 前一个RGV /// /// public RGVDevice Before() { var arr = AllRGVList.OrderBy(v => v.Position); var rgv = arr.FirstOrDefault(v => v.Position > Position); if (rgv == null) rgv = arr.LastOrDefault(v => v.Position < Position); return rgv; } /// /// 后一个RGV /// /// public RGVDevice After() { return new RGVDevice(new WCS_DEVICE()); } /// /// 两个RGV之间的距离 /// /// /// public float Distance(RGVDevice after) { return Math.Abs((Position - after.Position + Length) % Length); } /// /// 是否可用 /// /// public bool Valid() { return true; } /// /// 移动 /// /// public void Move(StationDeviceGroup addr) { } /// /// 选择出库 /// /// public void Pick(StationDeviceGroup addr) { } public void Put() { } public RGVDevice[] RgvAfter(float distance) { return AllRGVList.Where(v => Distance(v) < distance).ToArray(); } public bool StopedByMe(RGVDevice rgv) { var target = rgv.Data2.DestPosition_1; var station = Device.Find($"G{target}").Create(); return station.Distance(this) < station.Distance(rgv); } public StationDeviceGroup NextStation() { return new StationDeviceGroup(new WCS_DEVICE()); } } /// /// 堆垛机设备 /// public class SRMDevice : Device { public SRMDevice(WCS_DEVICE entity) : base(entity) { } /// /// 获取放货点 /// public List GetDeliveryPoint() { return Entity.ROUTES.Select(v => v.NEXT) //巷道 .SelectMany(v => v.ROUTES.Select(d => d.NEXT)) //放货点 .Where(v => v.IsConv()) //必须是输送线 .Select(v => new StationDevice(v)).ToList(); } } public class RGVStationLocation { public RGVStationLocation(string station, string stationLocation, string startingPoint, string endPoint) { Station = station; StationLocation = stationLocation; StartingPoint = startingPoint; EndPoint = endPoint; } /// /// 输送机设备组编号 /// public string Station { get; set; } /// /// 输送机在环轨中的位置 /// public string StationLocation { get; set; } /// /// RGV起始 /// public string StartingPoint { get; set; } /// /// RGV结束 /// public string EndPoint { get; set; } } }