| | |
| | | using System.ComponentModel; |
| | | using System.Drawing.Design; |
| | | using System.Linq; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | |
| | | 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 |
| | | { |
| | |
| | | if (machineState == value) |
| | | return; |
| | | |
| | | LogAsync(DateTime.Now, $"设备状态切换:{machineState.ToString()}->{value.ToString()}", ""); |
| | | machineState = value; |
| | | |
| | | switch (machineState) |
| | | Task.Run(() => |
| | | { |
| | | case MachineState.Ready: |
| | | lock (machineStateLock) |
| | | { |
| | | SwitchBeep(false); |
| | | SwitchLightRed(false); |
| | | SwitchLightYellow(false); |
| | | } |
| | | OnMachineStateChanged?.Invoke(machineState); |
| | | |
| | | Task.Run(() => |
| | | { |
| | | |
| | | while (MachineState == MachineState.Ready) |
| | | switch (machineState) |
| | | { |
| | | case MachineState.Ready: |
| | | lock (machineStateLock) |
| | | { |
| | | lock (machineStateLock) |
| | | { |
| | | SwitchLightGreen(true); |
| | | Thread.Sleep(1000); |
| | | SwitchLightGreen(false); |
| | | Thread.Sleep(1000); |
| | | } |
| | | SwitchBeep(false); |
| | | SwitchLightRed(false); |
| | | SwitchLightYellow(false); |
| | | } |
| | | }); |
| | | |
| | | 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) |
| | | Task.Run(() => |
| | | { |
| | | lock (machineStateLock) |
| | | while (MachineState == MachineState.Ready) |
| | | { |
| | | SwitchLightYellow(true); |
| | | SwitchLightGreen(true); |
| | | Thread.Sleep(1000); |
| | | SwitchLightYellow(false); |
| | | SwitchLightGreen(false); |
| | | Thread.Sleep(1000); |
| | | lock (machineStateLock) |
| | | { |
| | | SwitchLightGreen(true); |
| | | Thread.Sleep(1000); |
| | | SwitchLightGreen(false); |
| | | Thread.Sleep(1000); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | break; |
| | | case MachineState.Resetting: |
| | | lock (machineStateLock) |
| | | { |
| | | SwitchBeep(false); |
| | | SwitchLightRed(false); |
| | | SwitchLightGreen(false); |
| | | } |
| | | Task.Run(() => |
| | | { |
| | | while (MachineState == MachineState.Resetting) |
| | | }); |
| | | |
| | | break; |
| | | case MachineState.Running: |
| | | lock (machineStateLock) |
| | | { |
| | | lock (machineStateLock) |
| | | { |
| | | |
| | | SwitchLightYellow(true); |
| | | Thread.Sleep(1000); |
| | | SwitchLightYellow(false); |
| | | Thread.Sleep(1000); |
| | | } |
| | | SwitchBeep(false); |
| | | SwitchLightRed(false); |
| | | SwitchLightYellow(false); |
| | | SwitchLightGreen(true); |
| | | } |
| | | }); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | OnMachineStateChanged?.Invoke(machineState); |
| | | 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; |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | 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() |
| | |
| | | [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("未配置复位操作执行设备"); |
| | | // } |
| | | //} |
| | | |
| | | if (ResetTimer == null) |
| | | { |
| | | ResetTimer = new Timer(FullReset, null, -1, -1); |
| | |
| | | if (opConfig?.InputPara != null && opConfig.InputPara.Count > 0) |
| | | { |
| | | //大复位信号 |
| | | ResetTimer.Change(opConfig.InputPara[0] == 1 ? FULLRESETTIME * 1000 : -1, -1); |
| | | ResetTimer.Change(opConfig.InputPara[0] == 1 ? Config.FullResetRequiredDuration * 1000 : -1, -1); |
| | | |
| | | if (opConfig.InputPara[0] == 0) |
| | | return new ProcessResponse(true); |
| | |
| | | MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice); |
| | | (invokeDevice as MotionCardBase).ResetAlarm(); |
| | | |
| | | _isdoing = false; |
| | | RaisedAlarm(""); |
| | | OnCheckHintUpload?.Invoke("", false); |
| | | |
| | | //if (MachineState != MachineState.Pause) |
| | | //{ |
| | | MachineState = MachineState.Ready; |
| | | //} |
| | | //else |
| | | //{ |
| | | // LogAsync(DateTime.Now, "设备暂停中,无法复位", ""); |
| | | // return new ProcessResponse(true); |
| | | //} |
| | | |
| | | if (IsEmergencyStopped) |
| | | { |
| | | RaisedAlarm("急停按钮未恢复,请执行大复位"); |
| | | MachineState = MachineState.Alarm; |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | |
| | | |
| | | //if (opConfig.InputPara?.Count > 0) |
| | | //{ |
| | | // //大复位信号 |
| | | // ResetTimer.Change(-1, opConfig.InputPara[0] == 1 ? FULLRESETTIME * 1000 : -1); |
| | | //} |
| | | |
| | | //if (invokeDevice is MotionCardBase motionCard) |
| | | //{ |
| | | // motionCard.Run(opConfig); |
| | | //} |
| | | |
| | | LogAsync(DateTime.Now, "普通复位动作完成", ""); |
| | | OnResetDone?.Invoke(); |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | |
| | | [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 (invokeDevice == null) |
| | | // { |
| | | // invokeDevice = DeviceCollection.FirstOrDefault(u => u.Id == monitorSet.InvokeDevice); |
| | | // if (invokeDevice == null) |
| | | // throw new ProcessException("未配置大复位操作执行设备"); |
| | | // } |
| | | //} |
| | | |
| | | //if (invokeDevice is MotionCardBase motionCard) |
| | | //{ |
| | | // motionCard.Run(opConfig); |
| | | //} |
| | | if (MachineState == MachineState.Pause) |
| | | { |
| | | Resume(false); |
| | | } |
| | | |
| | | 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(); |
| | | |
| | |
| | | /// WaitHandle 暂停句柄 默认为非阻塞 可执行 |
| | | /// WaitResult 暂停标志 true 正常执行 false 暂停中 |
| | | /// </summary> |
| | | ManualWaitConfirm _pauseHandle = new ManualWaitConfirm() |
| | | { |
| | | WaitHandle = new ManualResetEvent(true), |
| | | WaitResult = true, |
| | | }; |
| | | MachineState _machineStateBeforePause = MachineState.Unknown; |
| | | //ManualWaitConfirm _pauseHandle = new ManualWaitConfirm() |
| | | //{ |
| | | // WaitHandle = new ManualResetEvent(true), |
| | | // WaitResult = true, |
| | | //}; |
| | | |
| | | 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) |
| | |
| | | throw new ProcessException("未获取板卡设备"); |
| | | |
| | | bool? isToPause = null; //true 暂停 false 继续 |
| | | if (opConfig.InputPara != null && opConfig.InputPara.Count > 0) |
| | | |
| | | if (opConfig.InputPara[0] == 10) |
| | | { |
| | | isToPause = opConfig.InputPara[0] == 1; |
| | | isToPause = false; |
| | | } |
| | | else if (opConfig.InputPara[0] == 11) |
| | | { |
| | | isToPause = true; |
| | | } |
| | | |
| | | if (isToPause == null) |
| | | { |
| | | if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡暂停动作 |
| | | motionDevice.SetImmediatePause(); |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Reset(); |
| | | _pauseHandle.WaitResult = true; |
| | | _machineStateBeforePause = MachineState; |
| | | MachineState = MachineState.Pause; |
| | | } |
| | | else if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡恢复动作 |
| | | motionDevice.ResetImmediatePause(); |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Set(); |
| | | _pauseHandle.WaitResult = false; |
| | | MachineState = _machineStateBeforePause; |
| | | } |
| | | IsManualPaused = !IsManualPaused; |
| | | } |
| | | else |
| | | { |
| | | if (isToPause.Value) |
| | | { |
| | | if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡暂停动作 |
| | | motionDevice.SetImmediatePause(); |
| | | #endregion |
| | | //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.Reset(); |
| | | // //_pauseHandle.WaitResult = true; |
| | | // MachineState = MachineState.Pause; |
| | | // } |
| | | //} |
| | | //else |
| | | //{ |
| | | // if (!_pauseHandle.WaitResult) |
| | | // { |
| | | // //#region 板卡恢复动作 |
| | | // //motionDevice.ResetImmediatePause(); |
| | | // //#endregion |
| | | |
| | | _pauseHandle.WaitHandle.Set(); |
| | | _pauseHandle.WaitResult = false; |
| | | MachineState = _machineStateBeforePause; |
| | | } |
| | | } |
| | | // //_pauseHandle.WaitHandle.Set(); |
| | | // //_pauseHandle.WaitResult = false; |
| | | // MachineState = _machineStatePre; |
| | | // } |
| | | //} |
| | | |
| | | IsManualPaused = isToPause.Value; |
| | | } |
| | | |
| | | return new ProcessResponse(_pauseHandle.WaitResult); |
| | | return new ProcessResponse(IsManualPaused); |
| | | } |
| | | |
| | | ////[ProcessMethod("", "PauseJob", "暂停流程", InvokeType.TestInvoke)] |
| | |
| | | { |
| | | 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; |
| | | get => (!Config.IsSafetyDoorBlocked) && isSafetyDoorTrigged; |
| | | set |
| | | { |
| | | isSafetyDoorTrigged = value; |
| | | CheckMachinePauseState(); |
| | | } |
| | | } |
| | | public bool IsSafetyBeamTrigged |
| | | { |
| | | get => !Config.IsSafetyBeamBlocked && isSafetyBeamTrigged; |
| | | set => isSafetyBeamTrigged = value; |
| | | 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; |
| | | object _pauseLock = new object(); |
| | | private async void CheckMachinePauseState() |
| | | { |
| | | await Task.Run(() => |
| | | { |
| | | lock (_pauseLock) |
| | | { |
| | | 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 || _machineStateBeforePause == MachineState.Ready) |
| | | { |
| | | Resume(true); |
| | | } |
| | | _pausedHandle.Set(); |
| | | RaisedAlarm(""); |
| | | MachineState = _machineStateBeforePause; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ); |
| | | } |
| | | |
| | | public bool IsMachinePaused |
| | | { |
| | | get => IsSafetyBeamTrigged || IsSafetyDoorTrigged || IsManualPaused; |
| | | } |
| | | |
| | | [ProcessMethod("", "SafetyDoorSignal", "安全门信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)] |
| | | [MethodImpl(MethodImplOptions.Synchronized)] |
| | | 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("安全门监控未配置输入信号"); |
| | | |
| | |
| | | if (IsSafetyDoorTrigged) |
| | | { |
| | | RaisedAlarm("安全门未正常关闭"); |
| | | MachineState = MachineState.Alarm; |
| | | } |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | [ProcessMethod("", "SafetyBeamSignal", "安全光幕信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)] |
| | | [MethodImpl(MethodImplOptions.Synchronized)] |
| | | public ProcessResponse SafetyBeamSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | { |
| | | if (MachineState != MachineState.Running || MachineState != MachineState.Alarm) |
| | | return new ProcessResponse(true); |
| | | |
| | | if (opConfig.InputPara == null || opConfig.InputPara.Count == 0) |
| | | throw new ProcessException("安全光幕监控未配置输入信号"); |
| | | |
| | |
| | | if (IsSafetyBeamTrigged) |
| | | { |
| | | RaisedAlarm("安全光线被遮挡"); |
| | | MachineState = MachineState.Alarm; |
| | | } |
| | | |
| | | return new ProcessResponse(true); |
| | |
| | | |
| | | IsEmergencyStopped = opConfig.InputPara[0] == 0; |
| | | |
| | | if (IsEmergencyStopped) |
| | | if (isEmergencyStopped) |
| | | { |
| | | RaisedAlarm("急停按钮被拍下"); |
| | | MachineState = MachineState.Alarm; |