using Bro.Common.Base;
|
using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Drawing.Design;
|
using System.Linq;
|
using System.Runtime.CompilerServices;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using static Bro.Common.Helper.EnumHelper;
|
|
namespace Bro.M071.Process
|
{
|
public partial class M071Process
|
{
|
public Timer ResetTimer = null;
|
|
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;
|
|
Task.Run(() =>
|
{
|
OnMachineStateChanged?.Invoke(machineState);
|
|
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;
|
}
|
});
|
}
|
}
|
|
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}未配置蜂鸣器输出索引", "");
|
}
|
|
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 (ResetTimer == null)
|
{
|
ResetTimer = new Timer(FullReset, null, -1, -1);
|
}
|
|
if (opConfig?.InputPara != null && opConfig.InputPara.Count > 0)
|
{
|
//大复位信号
|
ResetTimer.Change(opConfig.InputPara[0] == 1 ? Config.FullResetRequiredDuration * 1000 : -1, -1);
|
|
if (opConfig.InputPara[0] == 0)
|
return new ProcessResponse(true);
|
}
|
|
if (!IsAllowedWork)
|
{
|
LogAsync(DateTime.Now, $"{SafetyMsg},复位失败", "");
|
return new ProcessResponse(false);
|
}
|
|
MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice);
|
(invokeDevice as MotionCardBase).ResetAlarm();
|
|
_isdoing = false;
|
_pausedHandle.Set();
|
|
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);
|
}
|
|
LogAsync(DateTime.Now, "普通复位动作完成", "");
|
OnResetDone?.Invoke();
|
|
return new ProcessResponse(true);
|
}
|
|
private void FullReset(object state)
|
{
|
try
|
{
|
FullReset(null, null, null);
|
}
|
catch (Exception ex)
|
{
|
ExceptionRaisedInMonitor(ex);
|
}
|
}
|
|
//[ProcessMethod("MotionCardOperationConfigCollection", "FullReset", "大复位操作", InvokeType.TestInvoke)]
|
[ProcessMethod("MotionCardBase", "FullReset", "大复位操作", InvokeType.TestInvoke)]
|
public ProcessResponse FullReset(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
|
{
|
if (!IsAllowedWork)
|
{
|
LogAsync(DateTime.Now, $"{SafetyMsg},大复位失败", "");
|
return new ProcessResponse(false);
|
}
|
|
if (MachineState == MachineState.Pause)
|
{
|
Resume(false);
|
}
|
|
MachineState = MachineState.Resetting;
|
MotionCardDefaultRun("FullReset", ref opConfig, ref invokeDevice);
|
|
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);
|
}
|
|
/// <summary>
|
/// 暂停标志
|
/// WaitHandle 暂停句柄 默认为非阻塞 可执行
|
/// WaitResult 暂停标志 true 正常执行 false 暂停中
|
/// </summary>
|
//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)
|
{
|
if (!_statesAllowPause.Contains(MachineState))
|
return new ProcessResponse(-999);
|
|
MotionCardBase motionDevice = sourceDevice as MotionCardBase;
|
if (motionDevice == null)
|
{
|
motionDevice = DeviceCollection.FirstOrDefault(u => u is MotionCardBase) as MotionCardBase;
|
}
|
|
if (motionDevice == null)
|
throw new ProcessException("未获取板卡设备");
|
|
bool? isToPause = null; //true 暂停 false 继续
|
|
if (opConfig.InputPara[0] == 10)
|
{
|
isToPause = false;
|
}
|
else if (opConfig.InputPara[0] == 11)
|
{
|
isToPause = true;
|
}
|
|
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("", "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)
|
{
|
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, "红色灯未配置正确输出索引", "");
|
}
|
}
|
|
public void SwitchLightYellow(bool isOn)
|
{
|
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, "黄色灯未配置正确输出索引", "");
|
}
|
}
|
|
public void SwitchLightGreen(bool isOn)
|
{
|
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, "绿色灯未配置正确输出索引", "");
|
}
|
}
|
|
public void SwitchLight(bool isOn)
|
{
|
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, "照明灯未配置正确输出索引", "");
|
}
|
}
|
|
public void SwitchBeep(bool isOn)
|
{
|
if (Config.IsBeepBlocked)
|
return;
|
|
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, "蜂鸣器未配置正确输出索引", "");
|
}
|
}
|
#endregion
|
|
private void MotionCardDefaultRun(string methodCode, ref IOperationConfig opConfig, ref IDevice invokeDevice)
|
{
|
IMonitorSet monitorSet = null;
|
if (opConfig == null || !(opConfig is MotionCardOperationConfigBase))
|
{
|
monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == methodCode);
|
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 (invokeDevice is MotionCardBase motionCard)
|
{
|
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;
|
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("安全门监控未配置输入信号");
|
|
IsSafetyDoorTrigged = opConfig.InputPara[0] == 0;
|
|
if (IsSafetyDoorTrigged)
|
{
|
RaisedAlarm("安全门未正常关闭");
|
}
|
|
return new ProcessResponse(true);
|
}
|
|
[ProcessMethod("", "SafetyBeamSignal", "安全光幕信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)]
|
[MethodImpl(MethodImplOptions.Synchronized)]
|
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
|
}
|
}
|