From b5e7fa2db4ac36fdb7bf9fd330d12a72ade9d483 Mon Sep 17 00:00:00 2001
From: patrick.xu <patrick.xu@broconcentric.com>
Date: 星期日, 24 一月 2021 15:07:26 +0800
Subject: [PATCH] 0124

---
 src/Bro.M071.Process/M071Process_MotionCard.cs |  743 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 634 insertions(+), 109 deletions(-)

diff --git a/src/Bro.M071.Process/M071Process_MotionCard.cs b/src/Bro.M071.Process/M071Process_MotionCard.cs
index 98ce638..8806106 100644
--- a/src/Bro.M071.Process/M071Process_MotionCard.cs
+++ b/src/Bro.M071.Process/M071Process_MotionCard.cs
@@ -17,75 +17,255 @@
     public partial class M071Process
     {
         public Timer ResetTimer = null;
-        const int FULLRESETTIME = 5;
 
+        object machineStateLock = new object();
+        //MachineState _machineStatePre = MachineState.Unknown;
         MachineState machineState = MachineState.Unknown;
         public MachineState MachineState
         {
             get => machineState;
             set
             {
+                if (machineState == value)
+                    return;
+
+                LogAsync(DateTime.Now, $"璁惧鐘舵�佸垏鎹�:{machineState.ToString()}->{value.ToString()}", "");
                 machineState = value;
 
-                switch (machineState)
+                Task.Run(() =>
                 {
-                    case MachineState.Ready:
-                        break;
-                    case MachineState.Running:
-                        break;
-                    case MachineState.Alarm:
-                        break;
-                    case MachineState.Pause:
-                        break;
-                    default:
-                        break;
-                }
+                    switch (machineState)
+                    {
+                        case MachineState.Ready:
+                            lock (machineStateLock)
+                            {
+                                SwitchBeep(false);
+                                SwitchLightRed(false);
+                                SwitchLightYellow(false);
+                            }
+
+                            Task.Run(() =>
+                            {
+                                while (MachineState == MachineState.Ready)
+                                {
+                                    lock (machineStateLock)
+                                    {
+                                        SwitchLightGreen(true);
+                                        Thread.Sleep(1000);
+                                        SwitchLightGreen(false);
+                                        Thread.Sleep(1000);
+                                    }
+                                }
+                            });
+
+                            break;
+                        case MachineState.Running:
+                            lock (machineStateLock)
+                            {
+                                SwitchBeep(false);
+                                SwitchLightRed(false);
+                                SwitchLightYellow(false);
+                                SwitchLightGreen(true);
+                            }
+                            break;
+                        case MachineState.Alarm:
+                            lock (machineStateLock)
+                            {
+                                SwitchBeep(true);
+                                SwitchLightRed(true);
+                                SwitchLightYellow(false);
+                                SwitchLightGreen(false);
+                            }
+                            break;
+                        case MachineState.Pause:
+                            lock (machineStateLock)
+                            {
+                                SwitchBeep(false);
+                                SwitchLightRed(false);
+                            }
+                            Task.Run(() =>
+                            {
+                                while (MachineState == MachineState.Pause)
+                                {
+                                    lock (machineStateLock)
+                                    {
+                                        SwitchLightYellow(true);
+                                        SwitchLightGreen(true);
+                                        Thread.Sleep(1000);
+                                        SwitchLightYellow(false);
+                                        SwitchLightGreen(false);
+                                        Thread.Sleep(1000);
+                                    }
+                                }
+                            });
+                            break;
+                        case MachineState.Resetting:
+                            lock (machineStateLock)
+                            {
+                                SwitchBeep(false);
+                                SwitchLightRed(false);
+                                SwitchLightGreen(false);
+                            }
+                            Task.Run(() =>
+                            {
+                                while (MachineState == MachineState.Resetting)
+                                {
+                                    lock (machineStateLock)
+                                    {
+                                        SwitchLightYellow(true);
+                                        Thread.Sleep(1000);
+                                        SwitchLightYellow(false);
+                                        Thread.Sleep(1000);
+                                    }
+                                }
+                            });
+                            break;
+                        default:
+                            break;
+                    }
+                });
 
                 OnMachineStateChanged?.Invoke(machineState);
             }
         }
 
+        private void Pause()
+        {
+            #region 鏉垮崱鏆傚仠鍔ㄤ綔
+            outputCtrlCard.SetImmediatePause();
+            #endregion
+
+            //_pauseHandle.WaitHandle.Reset();
+            //_pauseHandle.WaitResult = true;
+        }
+
+        private void Resume(bool isResumeContinueMoving)
+        {
+            #region 鏉垮崱鎭㈠鍔ㄤ綔
+            outputCtrlCard.ResetImmediatePause(isResumeContinueMoving);
+            #endregion
+
+            //_pauseHandle.WaitHandle.Set();
+            //_pauseHandle.WaitResult = false;
+        }
+
+        private void MotionCardSettingCheck()
+        {
+            IDevice device = DeviceCollection.FirstOrDefault(u => u is IMotionCard);
+            if (device?.InitialConfig is MotionCardInitialConfigBase iConfig)
+            {
+                outputCtrlCard = device as MotionCardBase;
+
+                var redDefinition = iConfig.IODefinitionCollection.FirstOrDefault(u => u.IOPreStatement == IOPrestatement.Light_Red);
+                if (redDefinition != null)
+                {
+                    index_RedLight = redDefinition.IONum;
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, $"{iConfig.Name}鏈厤缃孩鑹茬伅杈撳嚭绱㈠紩", "");
+                }
+
+                var greenDefinition = iConfig.IODefinitionCollection.FirstOrDefault(u => u.IOPreStatement == IOPrestatement.Light_Green);
+                if (greenDefinition != null)
+                {
+                    index_GreenLight = greenDefinition.IONum;
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, $"{iConfig.Name}鏈厤缃豢鑹茬伅杈撳嚭绱㈠紩", "");
+                }
+
+                var yellowDefinition = iConfig.IODefinitionCollection.FirstOrDefault(u => u.IOPreStatement == IOPrestatement.Light_Yellow);
+                if (yellowDefinition != null)
+                {
+                    index_YellowLight = yellowDefinition.IONum;
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, $"{iConfig.Name}鏈厤缃粍鑹茬伅杈撳嚭绱㈠紩", "");
+                }
+
+                var beepDefinition = iConfig.IODefinitionCollection.FirstOrDefault(u => u.IOPreStatement == IOPrestatement.Beep);
+                if (beepDefinition != null)
+                {
+                    index_Beep = beepDefinition.IONum;
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, $"{iConfig.Name}鏈厤缃渹楦e櫒杈撳嚭绱㈠紩", "");
+                }
+
+                var lightDefinition = iConfig.IODefinitionCollection.FirstOrDefault(u => u.IOPreStatement == IOPrestatement.Light);
+                if (lightDefinition != null)
+                {
+                    index_NormalLight = lightDefinition.IONum;
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, $"{iConfig.Name}鏈厤缃棩鍏夌伅杈撳嚭绱㈠紩", "");
+                }
+            }
+            else
+            {
+                LogAsync(DateTime.Now, "鏈厤缃澘鍗¤澶�", "");
+            }
+        }
+
+        [ProcessMethod("MotionCardBase", "GotoReadyPosition", "杩愬姩鍒伴澶囦綅缃�", InvokeType.TestInvoke)]
+        public ProcessResponse GotoReadyPosition(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        {
+            MotionCardDefaultRun("GotoReadyPosition", ref opConfig, ref invokeDevice);
+
+            LogAsync(DateTime.Now, "杩愬姩鍒伴澶囦綅缃畬鎴�", "");
+
+            return new ProcessResponse(true);
+        }
+
         [ProcessMethod("MotionCardBase", "Reset", "绠�鍗曞浣嶆搷浣�", InvokeType.TestInvoke)]
         public ProcessResponse Reset(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
         {
-            //if (opConfig == null)
-            //{
-            //    var monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == "Reset");
-            //    if (monitorSet == null)
-            //        throw new ProcessException("鏈厤缃粯璁ゅ浣嶆搷浣�");
-
-            //    opConfig = monitorSet.OpConfig;
-            //    if (opConfig == null)
-            //        throw new ProcessException("鏈厤缃浣嶆搷浣滃叿浣撻厤缃姩浣�");
-
-            //    if (invokeDevice == null)
-            //    {
-            //        invokeDevice = DeviceCollection.FirstOrDefault(u => u.Id == monitorSet.InvokeDevice);
-            //        if (invokeDevice == null)
-            //            throw new ProcessException("鏈厤缃浣嶆搷浣滄墽琛岃澶�");
-            //    }
-            //}
-
-            MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice);
-
-            RaisedAlarm("");
-            MachineState = MachineState.Ready;
-
             if (ResetTimer == null)
             {
                 ResetTimer = new Timer(FullReset, null, -1, -1);
             }
 
-            if (opConfig.InputPara.Count > 0)
+            if (opConfig?.InputPara != null && opConfig.InputPara.Count > 0)
             {
                 //澶у浣嶄俊鍙�
-                ResetTimer.Change(-1, opConfig.InputPara[0] == 1 ? FULLRESETTIME * 1000 : -1);
+                ResetTimer.Change(opConfig.InputPara[0] == 1 ? Config.FullResetRequiredDuration * 1000 : -1, -1);
+
+                if (opConfig.InputPara[0] == 0)
+                    return new ProcessResponse(true);
             }
 
-            //if (invokeDevice is MotionCardBase motionCard)
+            if (!IsAllowedWork)
+            {
+                LogAsync(DateTime.Now, $"{SafetyMsg}锛屽浣嶅け璐�", "");
+                return new ProcessResponse(false);
+            }
+
+            MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice);
+            (invokeDevice as MotionCardBase).ResetAlarm();
+
+            RaisedAlarm("");
+
+            //if (MachineState != MachineState.Pause)
             //{
-            //    motionCard.Run(opConfig);
+            MachineState = MachineState.Ready;
             //}
+            //else
+            //{
+            //    LogAsync(DateTime.Now, "璁惧鏆傚仠涓紝鏃犳硶澶嶄綅", "");
+            //    return new ProcessResponse(true);
+            //}
+
+            if (IsEmergencyStopped)
+            {
+                RaisedAlarm("鎬ュ仠鎸夐挳鏈仮澶嶏紝璇锋墽琛屽ぇ澶嶄綅");
+                MachineState = MachineState.Alarm;
+                return new ProcessResponse(true);
+            }
 
             LogAsync(DateTime.Now, "鏅�氬浣嶅姩浣滃畬鎴�", "");
 
@@ -94,43 +274,51 @@
 
         private void FullReset(object state)
         {
-            FullReset(null, null, null);
+            try
+            {
+                FullReset(null, null, null);
+            }
+            catch (Exception ex)
+            {
+                ExceptionRaisedInMonitor(ex);
+            }
         }
 
-        [ProcessMethod("MotionCardOperationConfigCollection", "FullReset", "澶у浣嶆搷浣�", InvokeType.TestInvoke)]
+        //[ProcessMethod("MotionCardOperationConfigCollection", "FullReset", "澶у浣嶆搷浣�", InvokeType.TestInvoke)]
+        [ProcessMethod("MotionCardBase", "FullReset", "澶у浣嶆搷浣�", InvokeType.TestInvoke)]
         public ProcessResponse FullReset(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
         {
-            //if (opConfig == null)
-            //{
-            //    var monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == "FullReset");
-            //    if (monitorSet == null)
-            //        throw new ProcessException("鏈厤缃粯璁ゅぇ澶嶄綅鎿嶄綔");
+            if (!IsAllowedWork)
+            {
+                LogAsync(DateTime.Now, $"{SafetyMsg}锛屽ぇ澶嶄綅澶辫触", "");
+                return new ProcessResponse(false);
+            }
 
-            //    opConfig = monitorSet.OpConfig;
-            //    if (opConfig == null)
-            //        throw new ProcessException("鏈厤缃ぇ澶嶄綅鎿嶄綔鍏蜂綋閰嶇疆鍔ㄤ綔");
+            if (MachineState == MachineState.Pause)
+            {
+                Resume(false);
+            }
 
-            //    if (invokeDevice == null)
-            //    {
-            //        invokeDevice = DeviceCollection.FirstOrDefault(u => u.Id == monitorSet.InvokeDevice);
-            //        if (invokeDevice == null)
-            //            throw new ProcessException("鏈厤缃ぇ澶嶄綅鎿嶄綔鎵ц璁惧");
-            //    }
-            //}
-
-            //if (invokeDevice is MotionCardBase motionCard)
-            //{
-            //    motionCard.Run(opConfig);
-            //}
-
+            MachineState = MachineState.Resetting;
             MotionCardDefaultRun("FullReset", ref opConfig, ref invokeDevice);
 
-            productionList.ForEach(u => u.Dispose());
-            productionList.Clear();
+            lock (productionLock)
+            {
+                productionList.ForEach(u => u.Dispose());
+                productionList.Clear();
+            }
 
             OnFullResetDone?.Invoke();
 
+            isFullResetCovered = true;
+
             LogAsync(DateTime.Now, "澶у浣嶅姩浣滃畬鎴�", "");
+
+            RaisedAlarm("");
+            MachineState = MachineState.Ready;
+
+            GotoReadyPosition(null, null, null);
+
             return new ProcessResponse(true);
         }
 
@@ -139,79 +327,252 @@
         /// WaitHandle 鏆傚仠鍙ユ焺  榛樿涓洪潪闃诲 鍙墽琛�
         /// WaitResult 鏆傚仠鏍囧織 true 姝e父鎵ц  false 鏆傚仠涓�
         /// </summary>
-        ManualWaitConfirm _pauseHandle = new ManualWaitConfirm()
-        {
-            WaitHandle = new ManualResetEvent(true),
-            WaitResult = true,
-        };
+        //ManualWaitConfirm _pauseHandle = new ManualWaitConfirm()
+        //{
+        //    WaitHandle = new ManualResetEvent(true),
+        //    WaitResult = true,
+        //};
 
-        [ProcessMethod("", "PauseJob", "鏆傚仠娴佺▼", InvokeType.TestInvoke)]
-        public ProcessResponse PauseJob(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        List<MachineState> _statesAllowPause = new List<MachineState>() { MachineState.Running, MachineState.Ready, MachineState.Pause };
+        [ProcessMethod("", "SwitchJobStatus", "娴佺▼鐘舵�佸垏鎹�", InvokeType.TestInvoke)]
+        public ProcessResponse SwitchJobStatus(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
         {
-            if (!_pauseHandle.WaitResult)
+            if (!_statesAllowPause.Contains(MachineState))
+                return new ProcessResponse(-999);
+
+            MotionCardBase motionDevice = sourceDevice as MotionCardBase;
+            if (motionDevice == null)
             {
-                #region 鏉垮崱鏆傚仠鍔ㄤ綔
-                #endregion
-
-                _pauseHandle.WaitHandle.Reset();
+                motionDevice = DeviceCollection.FirstOrDefault(u => u is MotionCardBase) as MotionCardBase;
             }
 
-            _pauseHandle.WaitResult = !_pauseHandle.WaitResult;
-            return new ProcessResponse(_pauseHandle.WaitResult);
-        }
+            if (motionDevice == null)
+                throw new ProcessException("鏈幏鍙栨澘鍗¤澶�");
 
-        [ProcessMethod("", "ResumeJob", "缁х画娴佺▼", InvokeType.TestInvoke)]
-        public ProcessResponse ResumeJob(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
-        {
-            if (_pauseHandle.WaitResult)
+            bool? isToPause = null; //true 鏆傚仠 false 缁х画
+
+            if (opConfig.InputPara[0] == 10)
             {
-                #region 鏉垮崱鎭㈠鍔ㄤ綔
-                #endregion
-
-                _pauseHandle.WaitHandle.Set();
+                isToPause = false;
+            }
+            else if (opConfig.InputPara[0] == 11)
+            {
+                isToPause = true;
             }
 
-            _pauseHandle.WaitResult = !_pauseHandle.WaitResult;
-            return new ProcessResponse(_pauseHandle.WaitResult);
+            if (isToPause == null)
+            {
+                IsManualPaused = !IsManualPaused;
+            }
+            else
+            {
+                //if (isToPause.Value)
+                //{
+                //    if (!_pauseHandle.WaitResult)
+                //    {
+                //        //#region 鏉垮崱鏆傚仠鍔ㄤ綔
+                //        //motionDevice.SetImmediatePause();
+                //        //#endregion
+
+                //        //_pauseHandle.WaitHandle.Reset();
+                //        //_pauseHandle.WaitResult = true;
+                //        MachineState = MachineState.Pause;
+                //    }
+                //}
+                //else
+                //{
+                //    if (!_pauseHandle.WaitResult)
+                //    {
+                //        //#region 鏉垮崱鎭㈠鍔ㄤ綔
+                //        //motionDevice.ResetImmediatePause();
+                //        //#endregion
+
+                //        //_pauseHandle.WaitHandle.Set();
+                //        //_pauseHandle.WaitResult = false;
+                //        MachineState = _machineStatePre;
+                //    }
+                //}
+
+                IsManualPaused = isToPause.Value;
+            }
+
+            return new ProcessResponse(IsManualPaused);
         }
 
-        [ProcessMethod("MotionCardBase", "SwitchLightRed", "鍒囨崲鎸囩ず鐏�-绾�", InvokeType.TestInvoke)]
-        public ProcessResponse SwitchLightRed(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        ////[ProcessMethod("", "PauseJob", "鏆傚仠娴佺▼", InvokeType.TestInvoke)]
+        //public ProcessResponse PauseJob(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    if (!_pauseHandle.WaitResult)
+        //    {
+        //        #region 鏉垮崱鏆傚仠鍔ㄤ綔
+        //        #endregion
+
+        //        _pauseHandle.WaitHandle.Reset();
+        //    }
+
+        //    _pauseHandle.WaitResult = !_pauseHandle.WaitResult;
+        //    return new ProcessResponse(_pauseHandle.WaitResult);
+        //}
+
+        ////[ProcessMethod("", "ResumeJob", "缁х画娴佺▼", InvokeType.TestInvoke)]
+        //public ProcessResponse ResumeJob(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    if (_pauseHandle.WaitResult)
+        //    {
+        //        #region 鏉垮崱鎭㈠鍔ㄤ綔
+        //        #endregion
+
+        //        _pauseHandle.WaitHandle.Set();
+        //    }
+
+        //    _pauseHandle.WaitResult = !_pauseHandle.WaitResult;
+        //    return new ProcessResponse(_pauseHandle.WaitResult);
+        //}
+
+        #region 涓夎壊鐏� & 铚傞福鍣�
+        //[ProcessMethod("MotionCardBase", "SwitchLightRed", "鍒囨崲鎸囩ず鐏�-绾�", InvokeType.TestInvoke)]
+        //public ProcessResponse SwitchLightRed(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    MotionCardDefaultRun("SwitchLightRed", ref opConfig, ref invokeDevice);
+        //    return new ProcessResponse(true);
+        //}
+
+        //[ProcessMethod("MotionCardBase", "SwitchLightYellow", "鍒囨崲鎸囩ず鐏�-榛�", InvokeType.TestInvoke)]
+        //public ProcessResponse SwitchLightYellow(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    return new ProcessResponse(true);
+        //}
+
+        //[ProcessMethod("MotionCardBase", "SwitchLightGreen", "鍒囨崲鎸囩ず鐏�-缁�", InvokeType.TestInvoke)]
+        //public ProcessResponse SwitchLightGreen(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    return new ProcessResponse(true);
+        //}
+
+        //[ProcessMethod("MotionCardBase", "SwitchBeep", "鍒囨崲铚傞福鍣�", InvokeType.TestInvoke)]
+        //public ProcessResponse SwitchBeep(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    return new ProcessResponse(true);
+        //}
+
+        //[ProcessMethod("MotionCardBase", "SwitchNormalLight", "鍒囨崲鏃ュ厜鐏�", InvokeType.TestInvoke)]
+        //public ProcessResponse SwitchNormalLight(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        //{
+        //    MotionCardDefaultRun("SwitchNormalLight", ref opConfig, ref invokeDevice);
+
+        //    return new ProcessResponse(true);
+        //}
+
+        int index_RedLight = -1;
+        int index_GreenLight = -1;
+        int index_YellowLight = -1;
+        int index_Beep = -1;
+        int index_NormalLight = -1;
+        MotionCardBase outputCtrlCard = null;
+
+        public void SwitchLightRed(bool isOn)
         {
-            MotionCardDefaultRun("SwitchLightRed", ref opConfig, ref invokeDevice);
-            return new ProcessResponse(true);
+            if (index_RedLight >= 0)
+            {
+                if (outputCtrlCard != null)
+                {
+                    outputCtrlCard.WriteOutput((short)index_RedLight, isOn ? IOValue.TRUE : IOValue.FALSE);
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, "鏈缃澘鍗¤緭鍑鸿澶�", "");
+                }
+            }
+            else
+            {
+                LogAsync(DateTime.Now, "绾㈣壊鐏湭閰嶇疆姝g‘杈撳嚭绱㈠紩", "");
+            }
         }
 
-        [ProcessMethod("MotionCardBase", "SwitchLightYellow", "鍒囨崲鎸囩ず鐏�-榛�", InvokeType.TestInvoke)]
-        public ProcessResponse SwitchLightYellow(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        public void SwitchLightYellow(bool isOn)
         {
-            return new ProcessResponse(true);
+            if (index_YellowLight >= 0)
+            {
+                if (outputCtrlCard != null)
+                {
+                    outputCtrlCard.WriteOutput((short)index_YellowLight, isOn ? IOValue.TRUE : IOValue.FALSE);
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, "鏈缃澘鍗¤緭鍑鸿澶�", "");
+                }
+            }
+            else
+            {
+                LogAsync(DateTime.Now, "榛勮壊鐏湭閰嶇疆姝g‘杈撳嚭绱㈠紩", "");
+            }
         }
 
-        [ProcessMethod("MotionCardBase", "SwitchLightGreen", "鍒囨崲鎸囩ず鐏�-缁�", InvokeType.TestInvoke)]
-        public ProcessResponse SwitchLightGreen(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        public void SwitchLightGreen(bool isOn)
         {
-            return new ProcessResponse(true);
+            if (index_GreenLight >= 0)
+            {
+                if (outputCtrlCard != null)
+                {
+                    outputCtrlCard.WriteOutput((short)index_GreenLight, isOn ? IOValue.TRUE : IOValue.FALSE);
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, "鏈缃澘鍗¤緭鍑鸿澶�", "");
+                }
+            }
+            else
+            {
+                LogAsync(DateTime.Now, "缁胯壊鐏湭閰嶇疆姝g‘杈撳嚭绱㈠紩", "");
+            }
         }
 
-        [ProcessMethod("MotionCardBase", "SwitchBeep", "鍒囨崲铚傞福鍣�", InvokeType.TestInvoke)]
-        public ProcessResponse SwitchBeep(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        public void SwitchLight(bool isOn)
         {
-            return new ProcessResponse(true);
+            if (index_NormalLight >= 0)
+            {
+                if (outputCtrlCard != null)
+                {
+                    outputCtrlCard.WriteOutput((short)index_NormalLight, isOn ? IOValue.TRUE : IOValue.FALSE);
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, "鏈缃澘鍗¤緭鍑鸿澶�", "");
+                }
+            }
+            else
+            {
+                LogAsync(DateTime.Now, "鐓ф槑鐏湭閰嶇疆姝g‘杈撳嚭绱㈠紩", "");
+            }
         }
 
-        [ProcessMethod("MotionCardBase", "SwitchNormalLight", "鍒囨崲鏃ュ厜鐏�", InvokeType.TestInvoke)]
-        public ProcessResponse SwitchNormalLight(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        public void SwitchBeep(bool isOn)
         {
-            MotionCardDefaultRun("SwitchNormalLight", ref opConfig, ref invokeDevice);
+            if (Config.IsBeepBlocked)
+                return;
 
-            return new ProcessResponse(true);
+            if (index_Beep >= 0)
+            {
+                if (outputCtrlCard != null)
+                {
+                    outputCtrlCard.WriteOutput((short)index_Beep, isOn ? IOValue.TRUE : IOValue.FALSE);
+                }
+                else
+                {
+                    LogAsync(DateTime.Now, "鏈缃澘鍗¤緭鍑鸿澶�", "");
+                }
+            }
+            else
+            {
+                LogAsync(DateTime.Now, "铚傞福鍣ㄦ湭閰嶇疆姝g‘杈撳嚭绱㈠紩", "");
+            }
         }
+        #endregion
 
         private void MotionCardDefaultRun(string methodCode, ref IOperationConfig opConfig, ref IDevice invokeDevice)
         {
             IMonitorSet monitorSet = null;
-            if (opConfig == null)
+            if (opConfig == null || !(opConfig is MotionCardOperationConfigBase))
             {
                 monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == methodCode);
                 if (monitorSet == null)
@@ -231,8 +592,172 @@
 
             if (invokeDevice is MotionCardBase motionCard)
             {
-                motionCard.Run(opConfig);
+                var response = motionCard.Run(opConfig);
+                if (!response.Result)
+                {
+                    throw new ProcessException($"{motionCard.Name}寮傚父锛寋response.Message}", null, ExceptionLevel.Fatal);
+                }
             }
         }
+
+        bool IsAllowedWork
+        {
+            get => !(IsSafetyBeamTrigged || IsSafetyDoorTrigged || IsEmergencyStopped);
+        }
+
+        string SafetyMsg
+        {
+            get => $"{(IsSafetyBeamTrigged ? "瀹夊叏鍏夊箷" : "")}{(IsSafetyDoorTrigged ? " 瀹夊叏闂�" : "")}{(IsEmergencyStopped ? " 鎬ュ仠鎸夐挳" : "")}瑙﹀彂涓�";
+        }
+
+        #region 瀹夊叏闂� & 瀹夊叏鍏夌嚎
+        bool isSafetyDoorTrigged = false;
+        bool isSafetyBeamTrigged = false;
+        bool isManualPaused = false;
+
+        public bool IsSafetyDoorTrigged
+        {
+            get => (!Config.IsSafetyDoorBlocked) && isSafetyDoorTrigged;
+            set
+            {
+                isSafetyDoorTrigged = value;
+                CheckMachinePauseState();
+            }
+        }
+        public bool IsSafetyBeamTrigged
+        {
+            get => (!Config.IsSafetyBeamBlocked) && isSafetyBeamTrigged;
+            set
+            {
+                isSafetyBeamTrigged = value;
+                CheckMachinePauseState();
+            }
+        }
+
+        public bool IsManualPaused
+        {
+            get => isManualPaused;
+            set
+            {
+                isManualPaused = value;
+                CheckMachinePauseState();
+            }
+        }
+
+        ManualResetEventSlim _pausedHandle = new ManualResetEventSlim(true);
+        MachineState _machineStateBeforePause = MachineState.Unknown;
+        private void CheckMachinePauseState()
+        {
+            //await Task.Run(() =>
+            {
+                if (IsMachinePaused)
+                {
+                    if (MachineState == MachineState.Ready || MachineState == MachineState.Running)
+                    {
+                        _machineStateBeforePause = MachineState;
+                    }
+                    MachineState = MachineState.Pause;
+                    _pausedHandle.Reset();
+
+                    if (_machineStateBeforePause == MachineState.Running)
+                    {
+                        Pause();
+                    }
+                }
+                else
+                {
+                    if (MachineState == MachineState.Pause)
+                    {
+                        if (_machineStateBeforePause == MachineState.Running)
+                        {
+                            Resume(true);
+                        }
+                        _pausedHandle.Set();
+                        RaisedAlarm("");
+                        MachineState = _machineStateBeforePause;
+                    }
+                }
+            }
+            //);
+        }
+
+        public bool IsMachinePaused
+        {
+            get => IsSafetyBeamTrigged || IsSafetyDoorTrigged || IsManualPaused;
+        }
+
+        [ProcessMethod("", "SafetyDoorSignal", "瀹夊叏闂ㄤ俊鍙风洃鎺э紝姝e父ON锛孫FF鏃舵姤璀�", InvokeType.TestInvoke)]
+        public ProcessResponse SafetyDoorSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        {
+            //if (MachineState != MachineState.Running && MachineState != MachineState.Pause)
+            //    return new ProcessResponse(true);
+
+            if (opConfig.InputPara == null || opConfig.InputPara.Count == 0)
+                throw new ProcessException("瀹夊叏闂ㄧ洃鎺ф湭閰嶇疆杈撳叆淇″彿");
+
+            IsSafetyDoorTrigged = opConfig.InputPara[0] == 0;
+
+            if (IsSafetyDoorTrigged)
+            {
+                RaisedAlarm("瀹夊叏闂ㄦ湭姝e父鍏抽棴");
+            }
+
+            return new ProcessResponse(true);
+        }
+
+        [ProcessMethod("", "SafetyBeamSignal", "瀹夊叏鍏夊箷淇″彿鐩戞帶锛屾甯窸N锛孫FF鏃舵姤璀�", InvokeType.TestInvoke)]
+        public ProcessResponse SafetyBeamSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        {
+            if (opConfig.InputPara == null || opConfig.InputPara.Count == 0)
+                throw new ProcessException("瀹夊叏鍏夊箷鐩戞帶鏈厤缃緭鍏ヤ俊鍙�");
+
+            IsSafetyBeamTrigged = opConfig.InputPara[0] == 0;
+
+            if (IsSafetyBeamTrigged)
+            {
+                RaisedAlarm("瀹夊叏鍏夌嚎琚伄鎸�");
+            }
+
+            return new ProcessResponse(true);
+        }
+        #endregion
+
+        #region 鎬ュ仠
+        bool isEmergencyStopped = false;
+        bool isFullResetCovered = true;
+        public bool IsEmergencyStopped
+        {
+            get => isEmergencyStopped && isFullResetCovered;
+            set
+            {
+                if (value)
+                {
+                    isFullResetCovered = false;
+                    isEmergencyStopped = true;
+                }
+                else
+                {
+                    isEmergencyStopped = false;
+                }
+            }
+        }
+
+        [ProcessMethod("", "EmergencyStop", "鎬ュ仠鎸夐挳琚媿涓�", InvokeType.TestInvoke)]
+        public ProcessResponse EmergencyStop(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        {
+            if (opConfig.InputPara == null || opConfig.InputPara.Count == 0)
+                throw new ProcessException("鎬ュ仠鎸夐挳鏈厤缃緭鍏ヤ俊鍙�");
+
+            IsEmergencyStopped = opConfig.InputPara[0] == 0;
+
+            if (isEmergencyStopped)
+            {
+                RaisedAlarm("鎬ュ仠鎸夐挳琚媿涓�");
+                MachineState = MachineState.Alarm;
+            }
+
+            return new ProcessResponse(true);
+        }
+        #endregion
     }
 }

--
Gitblit v1.8.0