using PlcSiemens.Core.Extension;
using ServiceCenter.Extensions;
using ServiceCenter.Logs;
using ServiceCenter.Redis;
using WCS.Core;
using WCS.Entity.Protocol.BCR;
using WCS.Entity.Protocol.Robot;
using WCS.Entity.Protocol.Station;
using WCS.Entity.Protocol.Truss;
namespace WCS.WorkEngineering.Extensions
{
///
/// 设备扩展
///
public static class DeviceExtension
{
#region 设备类型
public static List ProtocolInfos = new List();
///
/// 是否是巷道
///
/// 设备信息
///
public static bool IsTunnel(this Device source)
{
return source.HasFlag(DeviceFlags.巷道);
}
#endregion 设备类型
#region 标签判断
public static bool HasFlag(this Device device, params DeviceFlags[] flag)
{
return flag.Any(device.HasFlag);
}
#endregion 标签判断
#region 协议操作扩展
public static void AddProtocol(this Device device, int position, ushort db, string ip)
{
var info = new ProtocolInfo
{
Position = position,
DBInfo = new DBInfo
{
No = db,
PLCInfo = new PLCInfo
{
IP = ip,
Port = 102,
Rack = 0,
Slot = 1,
Type = PLCType.Siemens
}
}
};
ProtocolInfos.Add(info);
device.AddProtocol(info);
}
#endregion 协议操作扩展
#region 设备扩展方法
///
/// 入库站点是否被禁止
///
///
public static void 入库站点是否被禁止(this Device device)
{
var config = RedisHub.Default.Check("ForbidTubuEnter") ?? throw new Exception("请在Redis中配置入库口禁用");
var configs = config.Split(",");
if (configs.Contains(device.Entity.Code)) throw new KnownException("当前入库口已被禁用,请联系运维人员了解具体情况", LogLevelEnum.High);
}
///
/// 入库站点是否被禁止
///
///
public static void 入库站点是否被禁止(this Device device)
{
var config = RedisHub.Default.Check("ForbidTubuEnter") ?? throw new Exception("请在Redis中配置入库口禁用");
var configs = config.Split(",");
if (configs.Contains(device.Entity.Code)) throw new KnownException("当前入库口已被禁用,请联系运维人员了解具体情况", LogLevelEnum.High);
}
///
/// 入库站点是否被禁止
///
///
public static void 入库站点是否被禁止(this Device device)
{
var config = RedisHub.Default.Check("ForbidTubuEnter") ?? throw new Exception("请在Redis中配置入库口禁用");
var configs = config.Split(",");
if (configs.Contains(device.Entity.Code)) throw new KnownException("当前入库口已被禁用,请联系运维人员了解具体情况", LogLevelEnum.High);
}
///
/// 入库站点是否被禁止
///
///
public static void 入库站点是否被禁止(this Device device)
{
var config = RedisHub.Default.Check("ForbidTubuEnter") ?? throw new Exception("请在Redis中配置入库口禁用");
var configs = config.Split(",");
if (configs.Contains(device.Entity.Code)) throw new KnownException("当前入库口已被禁用,请联系运维人员了解具体情况", LogLevelEnum.High);
}
///
/// 入库站点是否满足执行条件
///
///
public static void 入库站点是否满足执行条件(this Device device)
{
}
///
/// 入库站点是否满足执行条件
///
///
public static void 入库站点是否满足执行条件(this Device device)
{
if (device.Data.VoucherNo != device.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{device.Data.VoucherNo}-DB521:{device.Data2.VoucherNo}", LogLevelEnum.High);
if (device.Data3.Status.HasFlag(StationStatus.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
if (device.Data3.Status.HasFlag(StationStatus.PH_Status) && device.Data2.Request == 0) throw new KnownException("有光电无请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.PH_Status) && device.Data2.Request == 1) throw new KnownException("无光电有请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.OT_Status)) throw new KnownException("站台货物信息与实际占用不一致", LogLevelEnum.Low);
if (!device.Data3.Status.HasFlag(StationStatus.PH_Status)) throw new KnownException("无光电", LogLevelEnum.Mid);
if (device.Data2.Request != 1) throw new KnownException("无请求", LogLevelEnum.Mid);
}
///
/// 入库站点是否满足执行条件
///
///
public static void 入库站点是否满足执行条件(this Device device)
{
if (device.Data.VoucherNo != device.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{device.Data.VoucherNo}-DB521:{device.Data2.VoucherNo}", LogLevelEnum.High);
if (device.Data3.Status.HasFlag(StationStatus.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
if (device.Data3.Status.HasFlag(StationStatus.PH_Status) && device.Data2.Request == 0) throw new KnownException("有光电无请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.PH_Status) && device.Data2.Request == 1) throw new KnownException("无光电有请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.OT_Status)) throw new KnownException("站台货物信息与实际占用不一致", LogLevelEnum.Low);
if (!device.Data3.Status.HasFlag(StationStatus.PH_Status)) throw new KnownException("无光电", LogLevelEnum.Mid);
if (device.Data2.Request != 1) throw new KnownException("无请求", LogLevelEnum.Mid);
}
///
/// 入库站点是否满足执行条件
///
///
public static void 入库站点是否满足执行条件(this Device device)
{
if (device.Data.VoucherNo != device.Data2.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{device.Data.VoucherNo}-DB521:{device.Data2.VoucherNo}", LogLevelEnum.High);
if (device.Data3.Status.HasFlag(StationStatus.Run)) throw new KnownException("设备运行中", LogLevelEnum.Low);
if (device.Data3.Status.HasFlag(StationStatus.PH_Status) && device.Data2.Request == 0) throw new KnownException("有光电无请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.PH_Status) && device.Data2.Request == 1) throw new KnownException("无光电有请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.OT_Status)) throw new KnownException("站台货物信息与实际占用不一致", LogLevelEnum.Low);
if (device.Data2.Request != 1.ToShort()) throw new KnownException("无请求", LogLevelEnum.Mid);
if (!device.Data3.Status.HasFlag(StationStatus.PH_Status)) throw new KnownException("无光电", LogLevelEnum.Mid);
if (device.Data2.Request != 1) throw new KnownException("无请求", LogLevelEnum.Mid);
}
///
/// 获取BCR码
///
///
public static string GetBCRCode(this IBCR81 bCR)
{
var barcode = bCR.Content.RemoveEscapeCharacters();
return barcode;
}
///
/// 获取历史扫码记录
///
///
public static List GetBcrCodeList(this IBCR83 bCR)
{
return new List() {
bCR.BcrCode1.RemoveEscapeCharacters(),
bCR.BcrCode2.RemoveEscapeCharacters(),
bCR.BcrCode3.RemoveEscapeCharacters(),
bCR.BcrCode4.RemoveEscapeCharacters(),
bCR.BcrCode5.RemoveEscapeCharacters(),
bCR.BcrCode6.RemoveEscapeCharacters(),
bCR.BcrCode7.RemoveEscapeCharacters(),
bCR.BcrCode8.RemoveEscapeCharacters(),
bCR.BcrCode9.RemoveEscapeCharacters(),
bCR.BcrCode10.RemoveEscapeCharacters(),
bCR.BcrCode11.RemoveEscapeCharacters() };
}
///
/// 获取缓存列表
///
///
public static IEnumerable GetBcrCodeList(this IStation525 station525)
{
var properties = station525.GetType().GetProperties().ToArray();
var index = 1;
for (var i = 1; i <= 50; i++)
{
var value = properties[index].GetValue(station525).ToString().RemoveEscapeCharacters();
if (!value.IsNullOrEmpty()) yield return value;
index += 7;
}
}
///
/// 获取缓存列表
///
///
public static IEnumerable GetTaskNoList(this ITruss531 station525)
{
var properties = station525.GetType().GetProperties().ToArray();
var index = 0;
for (var i = 0; i <= 59; i++)
{
var value = properties[index].GetValue(station525)!.ToInt();
if (value > 0) yield return value;
index += 1;
}
}
///
/// 获取缓存列表
///
///
public static IEnumerable GetTaskNoList(this IRobot531 station525)
{
var properties = station525.GetType().GetProperties().ToArray();
var index = 0;
for (var i = 0; i <= 29; i++)
{
var value = properties[index].GetValue(station525)!.ToInt();
if (value > 0) yield return value;
index += 1;
}
}
///
/// 通过仓库编码获取对应堆垛机信息
///
/// 仓库编码
///
public static string WarehouseToSrm(this string warehouseCode)
{
return warehouseCode switch
{
"1N" => "SRM1",
"1S" => "SRM2",
"2N" => "SRM3",
"2S" => "SRM4",
"3N" => "SRM5",
"3S" => "SRM6",
_ => "Error"
};
}
#endregion 设备扩展方法
///
/// 获取仓库号
///
public static string GetWareCode(this string add)
{
return add switch
{
#region 库一
//北
"SRM1" => "1N",
"2532" => "1N",
"2527" => "1N",
"2528" => "1N",
"418" => "1N",
"1606" => "1N",
"1666" => "1NR",
"1661" => "1NR",
"18" => "1N",
//南
"SRM2" => "1S",
"2732" => "1S",
"2727" => "1S",
"2728" => "1S",
"618" => "1S",
"1676" => "1SR",
"1681" => "1SR",
#endregion 库一
#region 库二
//北
"SRM3" => "2N",
"818" => "2N",
"1691" => "2NR",
"1696" => "2NR",
//南
"SRM4" => "2S",
"1018" => "2S",
"3128" => "2S",
"1711" => "2SR",
"1706" => "2SR",
#endregion 库二
#region 库二
//北
"SRM5" => "3N",
"1218" => "3N",
"1721" => "3NR",
"1726" => "3NR",
//南
"SRM6" => "3S",
"1418" => "3S",
"1736" => "3SR",
"1741" => "3SR",
#endregion 库二
_ => "",
};
}
}
///
/// 设备标签
///
[Flags]
public enum DeviceFlags : ulong
{
扫码 = 1L << 0,
称重 = 1L << 1,
外检 = 1L << 2,
顶升 = 1L << 3,
移栽 = 1L << 4,
旋转 = 1L << 5,
入库 = 1L << 6,
出库 = 1L << 7,
巷道口 = 1L << 8,
RGV口 = 1L << 9,
AGV取货站台口 = 1L << 10,
直轨 = 1L << 11,
弯轨 = 1L << 12,
环轨 = 1L << 13,
巷道 = 1L << 14,
堆垛机 = 1L << 15,
输送机 = 1L << 16,
#region 一轨双车堆垛机
一列堆垛机 = 1L << 23,
二列堆垛机 = 1L << 24,
#endregion 一轨双车堆垛机
RGV = 1L << 25,
桁架 = 1L << 26,
一楼扫码 = 1L << 27,
满轮主线第一次扫码 = 1L << 28,
主线分流点 = 1L << 29,
一楼叠盘机 = 1L << 30,
环形库分流点 = 1L << 31,
桁架分流点 = 1L << 32,
桁架缓存放行点 = 1L << 33,
桁架取货点 = 1L << 34,
拆盘机 = 1L << 35,
桁架码垛位 = 1L << 36,
环形库码垛工位 = 1L << 37,
Robot = 1L << 38,
桁架09缓存放行点 = 1L << 39,
桁架18缓存放行点 = 1L << 40,
桁架09异常缓存放行点 = 1L << 41,
二次码垛RGV取货口 = 1L << 42,
无交互触发设备 = 1L << 43,
}
///
/// 输送机段信息
///
public class StationSegmentInfo
{
///
/// 构造函数
///
/// 起始设备号
/// 结束设备号
/// ip
public StationSegmentInfo(int start, int end, string ip)
{
Start = start;
End = end;
Ip = ip;
}
///
/// 起始设备编号
///
public int Start { get; set; }
///
///结束设备编号
///
public int End { get; set; }
///
/// 输送机段所属IP
///
public string Ip { get; set; }
}
///
/// RGV信息
///
public class RgvSegmentInfo
{
///
/// 构造函数
///
///
/// ip
public RgvSegmentInfo(int code, string ip)
{
Code = code;
Ip = ip;
}
///
/// 设备编号
///
public int Code { get; set; }
///
/// 输送机段所属IP
///
public string Ip { get; set; }
}
///
/// 桁架信息
///
public class TrussSegmentInfo
{
///
/// 构造函数
///
///
/// ip
public TrussSegmentInfo(int code, string ip)
{
Code = code;
Ip = ip;
}
///
/// 设备编号
///
public int Code { get; set; }
///
/// 输送机段所属IP
///
public string Ip { get; set; }
}
///
/// 扫码器信息
///
public class BcrInfo
{
///
/// 构造函数
///
/// 设备编号
/// ip
public BcrInfo(string[] deviceNo, string ip)
{
DeviceNo = deviceNo;
Ip = ip;
}
///
/// 设备编号
///
public string[] DeviceNo { get; set; }
///
/// ip
///
public string Ip { get; set; }
}
///
/// 外形信息
///
public class ShapeInfo
{
///
/// 构造函数
///
/// 设备编号
/// ip
public ShapeInfo(int[] deviceNo, string ip)
{
DeviceNo = deviceNo;
Ip = ip;
}
///
/// 设备编号
///
public int[] DeviceNo { get; set; }
///
/// ip
///
public string Ip { get; set; }
}
///
/// 路径信息
///
public class RouteInfo
{
///
/// 构造函数
///
/// 起始点设备号
/// 下一个设备集合
public RouteInfo(string deviceCode, string[] nextList)
{
DeviceCode = deviceCode;
NextList = nextList;
}
///
/// 设备号
///
public string DeviceCode { get; set; }
///
/// 下一个设备
///
public string[] NextList { get; set; }
}
///
/// 缓存分流信息
///
public class CacheBcr
{
public CacheBcr(string bcrCode, short nextAdd)
{
BcrCode = bcrCode;
NextAdd = nextAdd;
}
///
/// 条码
///
public string BcrCode { get; set; }
///
/// 下一个地址
///
public short NextAdd { get; set; }
}
}