#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命å空间:WIDESEAWCS_QuartzJob * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * æè¿°ï¼šä¸€èˆ¬è¾“é€çº¿å®žçŽ°ç±» * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using HslCommunication; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_Communicator; using WIDESEAWCS_QuartzJob.ConveyorLine.Enum; using WIDESEAWCS_QuartzJob.DeviceBase; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.StackerCrane.Enum; namespace WIDESEAWCS_QuartzJob { [Description("输é€çº¿")] public class CommonConveyorLine : IConveyorLine { #region Private Member /// <summary> /// å †åž›æœºé€šè®¯å¯¹è±¡ /// </summary> private readonly BaseCommunicator _communicator; /// <summary> /// å †åž›æœºåè®®ä¿¡æ¯ /// </summary> private readonly List<DeviceProDTO> _deviceProDTOs; /// <summary> /// å †åž›æœºåè®®æ˜Žç»†ä¿¡æ¯ /// </summary> private readonly List<DeviceProtocolDetailDTO> _deviceProtocolDetailDTOs; /// <summary> /// è®¾å¤‡ç¼–å· /// </summary> public readonly string _deviceCode; /// <summary> /// 设备åç§° /// </summary> public readonly string _deviceName; private bool _heartStatr = true; private bool _isConnected = true; #endregion #region Public Member /// <summary> /// 输é€çº¿é€šè®¯å¯¹è±¡ /// </summary> public BaseCommunicator Communicator => _communicator; /// <summary> /// 输é€çº¿åè®®ä¿¡æ¯ /// </summary> public List<DeviceProDTO> DeviceProDTOs => _deviceProDTOs; /// <summary> /// 输é€çº¿åè®®æ˜Žç»†ä¿¡æ¯ /// </summary> public List<DeviceProtocolDetailDTO> DeviceProtocolDetailDTOs => _deviceProtocolDetailDTOs; /// <summary> /// è®¾å¤‡ç¼–å· /// </summary> public string DeviceCode => _deviceCode; /// <summary> /// 设备åç§° /// </summary> public string DeviceName => _deviceName; /// <summary> /// æ˜¯å¦æœ‰æ•…éšœ /// </summary> public bool IsFault => false; /// <summary> /// 通讯是å¦å·²è¿žæŽ¥ /// </summary> public bool IsConnected => Communicator.IsConnected && _isConnected; /// <summary> /// è®¾å¤‡çŠ¶æ€ /// </summary> public DeviceStatus Status => DeviceStatus.Offline; #endregion #region Constructor Function /// <summary> /// æž„é€ å‡½æ•° /// </summary> /// <param name="communicator">å †åž›æœºé€šè®¯å¯¹è±¡</param> /// <param name="deviceProDTOs">å †åž›æœºå议信æ¯</param> /// <param name="deviceProtocolDetailDTOs">å †åž›æœºå议明细信æ¯</param> /// <param name="deviceCode">设备编å·</param> /// <param name="deviceName">设备åç§°</param> public CommonConveyorLine(BaseCommunicator communicator, List<DeviceProDTO> deviceProDTOs, List<DeviceProtocolDetailDTO> deviceProtocolDetailDTOs, string deviceCode, string deviceName) { _communicator = communicator; _deviceProDTOs = deviceProDTOs; _deviceProtocolDetailDTOs = deviceProtocolDetailDTOs; _deviceCode = deviceCode; _deviceName = deviceName; CheckConnect(); } #endregion #region Private Method private void CheckConnect() { Task.Run(() => { while (_heartStatr) { try { DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(); if (devicePro == null) _isConnected = false; else Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType); _isConnected = true; } catch (Exception ex) { _isConnected = false; } Thread.Sleep(500); } }); } #endregion #region Public Method /// <summary> /// 读å–PLCå议地å€çš„æ•°æ® /// </summary> /// <typeparam name="TEnum">å议信æ¯çš„æžšä¸¾å¯¹è±¡ä¿¡æ¯ã€‚</typeparam> /// <typeparam name="TRsult">è¯»å–æ•°æ®çš„类型对象信æ¯ã€‚</typeparam> /// <param name="value">枚举值</param> /// <param name="deviceChildCode">设备åç¼–å·</param> /// <returns>读å–到的数æ®</returns> public TRsult GetValue<TEnum, TRsult>(TEnum value, string deviceChildCode) where TEnum : Enum { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == value.ToString() && x.DeviceChildCode == deviceChildCode); return devicePro == null ? throw new Exception() : (TRsult)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType); } /// <summary> /// 与设备的心跳 /// </summary> public void Heartbeat() { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="command"></param> /// <param name="deviceChildCode"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public bool SendCommand<T>(T command, string deviceChildCode) where T : IDataTransfer, new() { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == deviceChildCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { return false; } if (Communicator.WriteCustomer(devicePro.DeviceProAddress, command)) { return true; } return false; } /// <summary> /// 读å–PLCæ•°æ®ï¼Œè¿”回自定义对象 /// </summary> /// <typeparam name="T">泛型</typeparam> /// <param name="deviceChildCode">å设备编å·</param> /// <returns>返回自定义对象或抛出异常</returns> /// <exception cref="Exception"></exception> public T ReadCustomer<T>(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("未找到å议信æ¯:" + deviceChildCode); } else { return Communicator.ReadCustomer<T>(devicePro.DeviceProAddress); } } /// <summary> /// 读å–PLCæ•°æ®ï¼Œè¿”回自定义对象 /// </summary> /// <typeparam name="T">泛型</typeparam> /// <param name="deviceChildCode">å设备编å·</param> /// <param name="deviceProParamType">傿•°ç±»åž‹</param> /// <returns>返回自定义对象或抛出异常</returns> /// <exception cref="Exception"></exception> public T ReadCustomer<T>(string deviceChildCode, string deviceProParamType) where T : IDataTransfer, new() { if (!IsConnected) throw new Exception($"通讯连接错误,请检查网络"); DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == deviceProParamType && x.DeviceChildCode == deviceChildCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (devicePro == null) { throw new Exception("未找到å议信æ¯:" + deviceChildCode); } else { return Communicator.ReadCustomer<T>(devicePro.DeviceProAddress); } } /// <summary> /// æ ¹æ®å‚æ•°åç§°ã€è®¾å¤‡åç¼–å·å†™å…¥å¯¹åº”的数æ®ã€‚ /// </summary> /// <typeparam name="TEnum">傿•°å称枚举类型。</typeparam> /// <typeparam name="TValue">è¦å†™å…¥çš„æ•°æ®ç±»åž‹ã€‚</typeparam> /// <param name="enum">傿•°å称。</param> /// <param name="value">è¦å†™å…¥çš„æ•°æ®ã€‚</param> /// <param name="deviceChildCode">设备åç¼–å·å†™</param> /// <returns>返回写入æˆåŠŸæˆ–å¤±è´¥</returns> public bool SetValue<TEnum, TValue>(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() : Communicator.WriteObj(devicePro.DeviceProAddress, devicePro.DeviceDataType, value); } /// <summary> /// /// </summary> /// <param name="deviceChildCode"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public bool IsOccupied(string deviceChildCode) { if (Communicator.IsConnected) { List<DeviceProDTO> devicePros = _deviceProDTOs.Where(x => x.DeviceProParamType == ConveyorLineStatus.IsOccupied.ToString()).ToList(); if (devicePros.Count == 0) { //todo åè®®ä¿¡æ¯æœªèŽ·å–到时抛出异常 throw new Exception(); } for (int i = 0; i < devicePros.Count; i++) { object readStatus = Communicator.ReadAsObj(devicePros[i].DeviceProAddress, devicePros[i].DeviceDataType); //todo åè®®æ˜Žç»†ä¿¡æ¯æœªèŽ·å–到时抛出异常 DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePros[i].DeviceProParamName) ?? throw new Exception(); deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePros[i].DeviceProParamType && x.ProtocalDetailValue.Equals(readStatus.ToString())); if (deviceProtocolDetail != null) { return true; } return false; } } //todo 通讯未连接时抛出异常 return false; } public void Dispose() { _heartStatr = false; _communicator.Dispose(); GC.SuppressFinalize(this); } #endregion } }