using HslCommunication; using System.ComponentModel; using System.Reflection; using WIDESEAWCS_Communicator; using WIDESEAWCS_QuartzJob.DeviceBase; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.StackerCrane; using WIDESEAWCS_QuartzJob.StackerCrane.Enum; namespace WIDESEAWCS_QuartzJob { /// /// 一般堆垛机实现类,实现堆垛机接口层 /// [Description("堆垛机")] public class STK : IStackerCrane { #region Private Member /// /// 完成信号等待时间 /// private const int WaitTimeout = 20 * 6000; /// /// 完成信号读取频率 /// private const int ReadTimeout = 100; /// /// 堆垛机通讯对象 /// private BaseCommunicator _communicator; /// /// 堆垛机协议信息 /// private readonly List _deviceProDTOs; /// /// 堆垛机协议明细信息 /// private readonly List _deviceProtocolDetailDTOs; /// /// 设备编号 /// public readonly string _deviceCode; /// /// 设备名称 /// public readonly string _deviceName; /// /// 上一次任务号 /// private int _lastTaskNum; private bool _isChecked = false; private bool _heartStatr = true; private bool _isConnected = true; #endregion Private Member #region Public Member /// /// 堆垛机通讯对象 /// public BaseCommunicator Communicator => _communicator; /// /// 堆垛机协议信息 /// public List DeviceProDTOs => _deviceProDTOs; /// /// 堆垛机协议明细信息 /// public List DeviceProtocolDetailDTOs => _deviceProtocolDetailDTOs; /// /// 上一次执行的任务号 /// public int LastTaskNum => _lastTaskNum; /// /// 设备编号 /// public string DeviceCode => _deviceCode; /// /// 设备名称 /// public string DeviceName => _deviceName; /// /// 通讯是否已连接 /// public bool IsConnected => Communicator.IsConnected && _isConnected; /// /// 堆垛机任务完成事件 /// public event EventHandler StackerCraneTaskCompletedEventHandler; /// /// 堆垛机任务命令对象 /// public object StackerCraneTaskCommand { get; set; } /// /// 堆垛机完成事件是否已订阅 /// public bool IsEventSubscribed => StackerCraneTaskCompletedEventHandler != null; /// /// 堆垛机与MOM连接状态 /// public bool StackerOnline { get; set; } = false; public int? LastTaskType { get; set; } = null; public int CurrentTaskNum => throw new NotImplementedException(); public bool IsFault => throw new NotImplementedException(); public DeviceStatus Status => throw new NotImplementedException(); #endregion #region Constructor Function /// /// 构造函数 /// /// 堆垛机通讯对象 /// 堆垛机协议信息 /// 堆垛机协议明细信息 /// 设备编号 /// 设备名称 public STK(BaseCommunicator communicator, List deviceProDTOs, List deviceProtocolDetailDTOs, string deviceCode, string deviceName) { _communicator = communicator; _deviceProDTOs = deviceProDTOs; _deviceProtocolDetailDTOs = deviceProtocolDetailDTOs; _deviceCode = deviceCode; _deviceName = deviceName; } #endregion #region Private Method private void AnalysisData() { } #endregion #region Public Method /// /// 发送任务命令 /// /// 任务命令 /// public bool SendCommand(T command, string childCode) where T : IDataTransfer, new() { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == childCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { return false; } if (Communicator.WriteCustomer(devicePro.DeviceProAddress, command)) { StackerCraneTaskCommand = command; return true; } return false; } /// /// 读取PLC数据,返回自定义对象 /// /// 泛型 /// 子设备编号 /// 返回自定义对象或抛出异常 /// public T ReadCustomer(string deviceChildCode) where T : IDataTransfer, new() { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == "ReadDeviceCommand" && x.DeviceChildCode == deviceChildCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { throw new Exception("未找到协议信息"); } else { return Communicator.ReadCustomer(devicePro.DeviceProAddress); } } /// /// 读取PLC数据,返回自定义对象 /// /// 泛型 /// 子设备编号 /// 参数类型 /// 返回自定义对象或抛出异常 /// public T ReadCustomer(string deviceChildCode, string typeName) where T : IDataTransfer, new() { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == typeName && x.DeviceChildCode == deviceChildCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { throw new Exception("未找到协议信息"); } else { return Communicator.ReadCustomer(devicePro.DeviceProAddress); } } /// /// 根据参数名称、设备子编号写入对应的数据。 /// /// 参数名称枚举类型。 /// 要写入的数据类型。 /// 参数名称。 /// 要写入的数据。 /// 设备子编号写 /// 返回写入成功或失败 public bool SetValue(TEnum @enum, TValue value, string deviceChildCode) where TEnum : Enum where TValue : notnull { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == @enum.ToString() && x.DeviceChildCode == deviceChildCode); return devicePro == null ? throw new Exception($"写入数据错误,未在协议信息里面找到参数{value.ToString()}") : Communicator.WriteObj(devicePro.DeviceProAddress, devicePro.DeviceDataType, value); } /// /// 根据参数名称、设备子编号写入对应的数据。 /// /// 参数名称枚举类型。 /// 要写入的数据类型。 /// 参数名称。 /// 要写入的数据。 /// 设备子编号写 /// 返回写入成功或失败 public bool SetValue(TEnum @enum, TValue value, string deviceChildCode, string typeName) where TEnum : Enum where TValue : notnull { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamType == typeName && x.DeviceProParamName == @enum.ToString() && x.DeviceChildCode == deviceChildCode); return devicePro == null ? throw new Exception($"写入数据错误,未在协议信息里面找到参数{value.ToString()}") : Communicator.WriteObj(devicePro.DeviceProAddress, devicePro.DeviceDataType, value); } /// /// 根据参数名称读取堆垛机对应的数据。 /// /// 参数名称枚举类型。 /// 读取结果的返回值类型。 /// 参数名称。 /// 返回读取到的数据。 /// public TRsult GetValue(TEnum value, string childCode) where TEnum : Enum { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == value.ToString() && x.DeviceChildCode == childCode); return devicePro == null ? throw new Exception() : (TRsult)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType); } /// /// 与设备的心跳 /// public void Heartbeat() { } public void Dispose() { _heartStatr = false; _communicator.Dispose(); GC.SuppressFinalize(this); } public bool SendCommand(T command) where T : IDataTransfer, new() { throw new NotImplementedException(); } #endregion } }