From df5e63a89fa2fade5bf87d41f507740ea063e0e4 Mon Sep 17 00:00:00 2001 From: 刘磊 <1161824510@qq.com> Date: 星期六, 23 十一月 2024 14:58:13 +0800 Subject: [PATCH] 1 --- Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerStationCrane.cs | 489 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 489 insertions(+), 0 deletions(-) diff --git a/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerStationCrane.cs b/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerStationCrane.cs new file mode 100644 index 0000000..6c01a60 --- /dev/null +++ b/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerStationCrane.cs @@ -0,0 +1,489 @@ +锘�#region << 鐗� 鏈� 娉� 閲� >> +/*---------------------------------------------------------------- + * 鍛藉悕绌洪棿锛歐IDESEAWCS_QuartzJob + * 鍒涘缓鑰咃細鑳$搴� + * 鍒涘缓鏃堕棿锛�2024/8/2 16:13:36 + * 鐗堟湰锛歏1.0.0 + * 鎻忚堪锛氫竴鑸爢鍨涙満瀹炵幇绫伙紝瀹炵幇鍫嗗灈鏈烘帴鍙e眰 + * + * ---------------------------------------------------------------- + * 淇敼浜猴細 + * 淇敼鏃堕棿锛� + * 鐗堟湰锛歏1.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> + /// 涓�鑸爢鍨涙満瀹炵幇绫伙紝瀹炵幇鍫嗗灈鏈烘帴鍙e眰 + /// </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> + /// 褰撳墠姝e湪鎵ц鐨勪换鍔″彿 + /// </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 + } +} -- Gitblit v1.9.3