| | |
| | | *----------------------------------------------------------------*/ |
| | | #endregion << 版 本 注 释 >> |
| | | |
| | | using HslCommunication; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | |
| | | |
| | | namespace WIDESEAWCS_QuartzJob |
| | | { |
| | | [Description("输送线")] |
| | | public class CommonConveyorLine : IConveyorLine |
| | | { |
| | | #region Private Member |
| | |
| | | /// 堆垛机通讯对象 |
| | | /// </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; |
| | | |
| | | public bool IsFault => false; |
| | | /// <summary> |
| | | /// 通讯是否已连接 |
| | | /// </summary> |
| | | public bool IsConnected => Communicator.IsConnected && _isConnected; |
| | | |
| | | public bool IsConnected => Communicator.IsConnected; |
| | | |
| | | public DeviceStatus Status => DeviceStatus.Offline; |
| | | #endregion |
| | | |
| | | #region Constructor Function |
| | |
| | | _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(); |
| | | } |
| | | |
| | | public bool SendCommand(DeviceCommand command, string deviceChildCode) |
| | | /// <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() |
| | | { |
| | | DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == deviceChildCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); |
| | | if (devicePro == null) |
| | | if(Communicator is SiemensS7) |
| | | { |
| | | 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; |
| | | } |
| | | if (Communicator.WriteCustomer(devicePro.DeviceProAddress, command)) |
| | | else |
| | | { |
| | | return true; |
| | | throw new Exception("暂不支持除西门子之外的PLC"); |
| | | } |
| | | 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("未找到协议信息"); |
| | | } |
| | | 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) |
| | |
| | | //todo 通讯未连接时抛出异常 |
| | | return false; |
| | | } |
| | | |
| | | public void Dispose() |
| | | { |
| | | _heartStatr = false; |
| | | _communicator.Dispose(); |
| | | GC.SuppressFinalize(this); |
| | | } |
| | | #endregion |
| | | } |
| | | } |