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