¶Ô±ÈÐÂÎļþ |
| | |
| | | #region << ç æ¬ 注 é >> |
| | | /*---------------------------------------------------------------- |
| | | * å½å空é´ï¼WIDESEAWCS_QuartzJob |
| | | * å建è
ï¼è¡ç«¥åº |
| | | * å建æ¶é´ï¼2024/8/2 16:13:36 |
| | | * çæ¬ï¼V1.0.0 |
| | | * æè¿°ï¼ä¸è¬å åæºå®ç°ç±»ï¼å®ç°å åæºæ¥å£å± |
| | | * |
| | | * ---------------------------------------------------------------- |
| | | * ä¿®æ¹äººï¼ |
| | | * ä¿®æ¹æ¶é´ï¼ |
| | | * çæ¬ï¼V1.0.1 |
| | | * ä¿®æ¹è¯´æï¼ |
| | | * |
| | | *----------------------------------------------------------------*/ |
| | | #endregion << ç æ¬ 注 é >> |
| | | |
| | | using HslCommunication; |
| | | using Microsoft.AspNetCore.Http; |
| | | using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEAWCS_Communicator; |
| | | using WIDESEAWCS_Core.Enums; |
| | | using WIDESEAWCS_QuartzJob.DeviceBase; |
| | | using WIDESEAWCS_QuartzJob.DTO; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane.Enum; |
| | | |
| | | namespace WIDESEAWCS_QuartzJob |
| | | { |
| | | /// <summary> |
| | | /// ä¸è¬å åæºå®ç°ç±»ï¼å®ç°å åæºæ¥å£å± |
| | | /// </summary> |
| | | [Description("å åæº")] |
| | | public class CommonStackerStationCrane : IStackerCrane |
| | | { |
| | | #region Private Member |
| | | /// <summary> |
| | | /// å åæºé讯对象 |
| | | /// </summary> |
| | | private 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; |
| | | /// <summary> |
| | | /// ä¸ä¸æ¬¡ä»»å¡å· |
| | | /// </summary> |
| | | private int _lastTaskNum; |
| | | |
| | | private bool _isChecked = false; |
| | | |
| | | private bool _heartStatr = true; |
| | | |
| | | private bool _isConnected = true; |
| | | #endregion Private Member |
| | | |
| | | #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 DeviceStatus Status => GetStatus(); |
| | | |
| | | /// <summary> |
| | | /// ä¸ä¸æ¬¡æ§è¡çä»»å¡å· |
| | | /// </summary> |
| | | public int LastTaskNum => _lastTaskNum; |
| | | |
| | | /// <summary> |
| | | /// å½åæ£å¨æ§è¡çä»»å¡å· |
| | | /// </summary> |
| | | public int CurrentTaskNum => GetCurrentTaskNum(); |
| | | |
| | | /// <summary> |
| | | /// å åæºç¶æ |
| | | /// </summary> |
| | | public StackerCraneStatus StackerCraneStatusValue => GetStackerCraneStatus(); |
| | | |
| | | /// <summary> |
| | | /// å åæºç¶æä¸æè¯´æ |
| | | /// </summary> |
| | | public string StackerCraneStatusDes => GetEnumDes(StackerCraneStatusValue); |
| | | |
| | | /// <summary> |
| | | /// æèªå¨ç¶æ |
| | | /// </summary> |
| | | public StackerCraneAutoStatus StackerCraneAutoStatusValue => GetStackerCraneAutoStatus(); |
| | | |
| | | /// <summary> |
| | | /// æèªå¨ç¶æä¸æè¯´æ |
| | | /// </summary> |
| | | public string StackerCraneAutoStatusDes => GetEnumDes(StackerCraneAutoStatusValue); |
| | | |
| | | /// <summary> |
| | | /// ä½ä¸ç¶æ |
| | | /// </summary> |
| | | public StackerCraneWorkStatus StackerCraneWorkStatusValue => GetStackerCraneWorkStatus(); |
| | | |
| | | /// <summary> |
| | | /// ä½ä¸ç¶æä¸æè¯´æ |
| | | /// </summary> |
| | | public string StackerCraneWorkStatusDes => GetEnumDes(StackerCraneWorkStatusValue); |
| | | |
| | | /// <summary> |
| | | /// 设å¤ç¼å· |
| | | /// </summary> |
| | | public string DeviceCode => _deviceCode; |
| | | |
| | | /// <summary> |
| | | /// 设å¤åç§° |
| | | /// </summary> |
| | | public string DeviceName => _deviceName; |
| | | |
| | | /// <summary> |
| | | /// å åæºæ¯å¦ææ
é |
| | | /// </summary> |
| | | public bool IsFault => StackerCraneStatusValue == StackerCraneStatus.Fault; |
| | | |
| | | /// <summary> |
| | | /// é讯æ¯å¦å·²è¿æ¥ |
| | | /// </summary> |
| | | public bool IsConnected => Communicator.IsConnected && _isConnected; |
| | | |
| | | /// <summary> |
| | | /// å åæºä»»å¡å®æäºä»¶ |
| | | /// </summary> |
| | | public event EventHandler<StackerCraneTaskCompletedEventArgs> StackerCraneTaskCompletedEventHandler; |
| | | |
| | | /// <summary> |
| | | /// å åæºä»»å¡å½ä»¤å¯¹è±¡ |
| | | /// </summary> |
| | | public object StackerCraneTaskCommand { get; set; } |
| | | |
| | | /// <summary> |
| | | /// å åæºå®æäºä»¶æ¯å¦å·²è®¢é
|
| | | /// </summary> |
| | | public bool IsEventSubscribed => StackerCraneTaskCompletedEventHandler != null; |
| | | |
| | | /// <summary> |
| | | /// å åæºä¸MOMè¿æ¥ç¶æ |
| | | /// </summary> |
| | | public bool StackerOnline { get; set; } = false; |
| | | |
| | | public int? LastTaskType { get; set; } = null; |
| | | #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 CommonStackerStationCrane(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 |
| | | /// <summary> |
| | | /// æ ¹æ®å议读åå åæºç¶æ |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | /// <exception cref="Exception"></exception> |
| | | private DeviceStatus GetStatus() |
| | | { |
| | | if (IsFault) |
| | | { |
| | | return DeviceStatus.Fault; |
| | | } |
| | | else if (!IsConnected) |
| | | { |
| | | return DeviceStatus.Offline; |
| | | } |
| | | if (StackerCraneStatusValue == StackerCraneStatus.Normal && StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic) |
| | | { |
| | | if (StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) |
| | | { |
| | | return DeviceStatus.Idle; |
| | | } |
| | | else if (StackerCraneWorkStatusValue == StackerCraneWorkStatus.Putting || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUp || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUpCompleted || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutCompleted) |
| | | { |
| | | return DeviceStatus.Working; |
| | | } |
| | | } |
| | | return DeviceStatus.Unkonw; |
| | | } |
| | | |
| | | private int GetCurrentTaskNum() |
| | | { |
| | | DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(CurrentTaskNum)); |
| | | return devicePro == null ? throw new Exception() : (int)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åå åæºè®¾å¤ç¶æ |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private StackerCraneStatus GetStackerCraneStatus() |
| | | { |
| | | return Enum.Parse<StackerCraneStatus>(GetStatus(nameof(StackerCraneStatus))); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åå åæºæèªå¨ç¶æ |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private StackerCraneAutoStatus GetStackerCraneAutoStatus() |
| | | { |
| | | return Enum.Parse<StackerCraneAutoStatus>(GetStatus(nameof(StackerCraneAutoStatus))); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åå åæºå·¥ä½ç¶æ |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private StackerCraneWorkStatus GetStackerCraneWorkStatus() |
| | | { |
| | | return Enum.Parse<StackerCraneWorkStatus>(GetStatus(nameof(StackerCraneWorkStatus))); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæä¸¾è¯´æ |
| | | /// </summary> |
| | | /// <typeparam name="T">æä¸¾æ³å</typeparam> |
| | | /// <param name="value"></param> |
| | | /// <returns></returns> |
| | | private string GetEnumDes<T>(T value) where T : Enum |
| | | { |
| | | FieldInfo? fieldInfo = typeof(T).GetField(value.ToString()); |
| | | if (fieldInfo != null) |
| | | { |
| | | DescriptionAttribute? descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | if (descriptionAttribute != null) |
| | | { |
| | | return descriptionAttribute.Description; |
| | | } |
| | | return "æªå®ä¹"; |
| | | } |
| | | return "æªç¥"; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®åè®®åæ°ç±»åè·åç¶æ |
| | | /// </summary> |
| | | /// <param name="protocolParamType">åè®®åæ°ç±»å</param> |
| | | /// <returns></returns> |
| | | /// <exception cref="Exception"></exception> |
| | | private string GetStatus(string protocolParamType) |
| | | { |
| | | if (Communicator.IsConnected) |
| | | { |
| | | List<DeviceProDTO> devicePros = _deviceProDTOs.Where(x => x.DeviceProParamType == protocolParamType).ToList(); |
| | | if (devicePros.Count == 0) |
| | | { |
| | | 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 deviceProtocolDetail.ProtocolDetailType; |
| | | } |
| | | return StackerCraneStatus.Unkonw.ToString(); |
| | | } |
| | | } |
| | | //todo é讯æªè¿æ¥æ¶æåºå¼å¸¸ |
| | | return StackerCraneStatus.Unkonw.ToString(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ¯è¾ä¸¤ä¸ªå¼æ¯å¦ç¸çã |
| | | /// </summary> |
| | | /// <param name="value">第ä¸ä¸ªå¼ã</param> |
| | | /// <param name="paramValue">第äºä¸ªå¼ã</param> |
| | | /// <returns>è¿åæ¯è¾ç»æã</returns> |
| | | private bool Compare(object value, object paramValue) |
| | | { |
| | | return value.Equals(paramValue); |
| | | } |
| | | |
| | | 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> |
| | | /// åéä»»å¡å½ä»¤ |
| | | /// </summary> |
| | | /// <param name="command">ä»»å¡å½ä»¤</param> |
| | | /// <returns></returns> |
| | | public bool SendCommand<T>(T command) where T : IDataTransfer, new() |
| | | { |
| | | if (!IsConnected) throw new Exception($"éè®¯è¿æ¥é误ï¼è¯·æ£æ¥ç½ç»"); |
| | | DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand)).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); |
| | | if (devicePro == null) |
| | | { |
| | | return false; |
| | | } |
| | | if (Communicator.WriteCustomer(devicePro.DeviceProAddress, command)) |
| | | { |
| | | StackerCraneTaskCommand = command; |
| | | CheckStackerCraneTaskCompleted(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// çæµå åæºä»»å¡æ¯å¦å®æ(鲿¢ä»»å¡å®æäºä»¶çæµè¶
æ¶ï¼å®ä¹æå¨è§¦ååè½) |
| | | /// </summary> |
| | | public void CheckStackerCraneTaskCompleted() |
| | | { |
| | | if (_isChecked) |
| | | return; |
| | | |
| | | Task.Run(() => |
| | | { |
| | | _isChecked = true; |
| | | try |
| | | { |
| | | DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(StackerCraneWorkStatus)); |
| | | if (devicePro != null) |
| | | { |
| | | DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePro.DeviceProParamName && x.ProtocolDetailType == StackerCraneWorkStatus.WorkCompleted.ToString()); |
| | | if (deviceProtocolDetail != null) |
| | | { |
| | | OperateResult<TimeSpan> operateResult = new OperateResult<TimeSpan>(); |
| | | TypeCode typeCode = SiemensDBDataType.GetTypeCode(devicePro.DeviceDataType); |
| | | switch (typeCode) |
| | | { |
| | | case TypeCode.Boolean: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | case TypeCode.Byte: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | case TypeCode.Int16: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | case TypeCode.Int32: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | case TypeCode.UInt16: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | case TypeCode.UInt32: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | int taskNum = CurrentTaskNum; |
| | | if (operateResult.IsSuccess /*&& LastTaskNum != taskNum*/) |
| | | { |
| | | StackerCraneTaskCompletedEventArgs args = new(taskNum); |
| | | StackerCraneTaskCompletedEventHandler?.Invoke(this, args); |
| | | _lastTaskNum = taskNum; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | |
| | | } |
| | | finally |
| | | { |
| | | _isChecked = false; |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®åæ°å称读åå åæºå¯¹åºçæ°æ®ã |
| | | /// </summary> |
| | | /// <typeparam name="TEnum">åæ°åç§°æä¸¾ç±»åã</typeparam> |
| | | /// <typeparam name="TRsult">读åç»æçè¿åå¼ç±»åã</typeparam> |
| | | /// <param name="value">åæ°åç§°ã</param> |
| | | /// <returns>è¿å读åå°çæ°æ®ã</returns> |
| | | /// <exception cref="Exception"></exception> |
| | | public TRsult GetValue<TEnum, TRsult>(TEnum value) where TEnum : Enum |
| | | { |
| | | if (!IsConnected) throw new Exception($"éè®¯è¿æ¥é误ï¼è¯·æ£æ¥ç½ç»"); |
| | | DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == value.ToString()); |
| | | return devicePro == null ? throw new Exception() : (TRsult)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä¸è®¾å¤çå¿è·³ |
| | | /// </summary> |
| | | public void Heartbeat() |
| | | { |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®åæ°åç§°åå
¥å åæºå¯¹åºçæ°æ®ã |
| | | /// </summary> |
| | | /// <typeparam name="TEnum">åæ°åç§°æä¸¾ç±»åã</typeparam> |
| | | /// <typeparam name="TValue">è¦åå
¥çæ°æ®ç±»åã</typeparam> |
| | | /// <param name="enum">åæ°åç§°ã</param> |
| | | /// <param name="value">è¦åå
¥çæ°æ®ã</param> |
| | | /// <returns>è¿ååå
¥æåæå¤±è´¥</returns> |
| | | /// <exception cref="Exception"></exception> |
| | | public bool SetValue<TEnum, TValue>(TEnum @enum, TValue value) |
| | | where TEnum : Enum |
| | | where TValue : notnull |
| | | { |
| | | if (!IsConnected) throw new Exception($"éè®¯è¿æ¥é误ï¼è¯·æ£æ¥ç½ç»"); |
| | | DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == @enum.ToString()); |
| | | return devicePro == null ? throw new Exception() : Communicator.WriteObj(devicePro.DeviceProAddress, devicePro.DeviceDataType, value); |
| | | } |
| | | |
| | | public void Dispose() |
| | | { |
| | | _heartStatr = false; |
| | | _communicator.Dispose(); |
| | | GC.SuppressFinalize(this); |
| | | } |
| | | #endregion |
| | | } |
| | | } |