| | |
| | | public Timer ResetTimer = null; |
| | | const int FULLRESETTIME = 5; |
| | | |
| | | object machineStateLock = new object(); |
| | | MachineState machineState = MachineState.Unknown; |
| | | public MachineState MachineState |
| | | { |
| | |
| | | switch (machineState) |
| | | { |
| | | case MachineState.Ready: |
| | | lock (machineStateLock) |
| | | { |
| | | SwitchBeep(false); |
| | | SwitchLightRed(false); |
| | | SwitchLightYellow(false); |
| | | } |
| | | |
| | | Task.Run(() => |
| | | { |
| | | lock (machineStateLock) |
| | | { |
| | | while (MachineState == MachineState.Ready) |
| | | { |
| | | 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(() => |
| | | { |
| | | lock (machineStateLock) |
| | | { |
| | | while (MachineState == MachineState.Pause) |
| | | { |
| | | 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(() => |
| | | { |
| | | lock (machineStateLock) |
| | | { |
| | | while (MachineState == MachineState.Resetting) |
| | | { |
| | | SwitchLightYellow(true); |
| | | Thread.Sleep(1000); |
| | | SwitchLightYellow(false); |
| | | Thread.Sleep(1000); |
| | | } |
| | | } |
| | | }); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | OnMachineStateChanged?.Invoke(machineState); |
| | | } |
| | | } |
| | | |
| | | 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, "未配置板卡设备", ""); |
| | | } |
| | | } |
| | | |
| | |
| | | // } |
| | | //} |
| | | |
| | | if (IsSafetyBeamTrigged || IsSafetyDoorTrigged) |
| | | { |
| | | LogAsync(DateTime.Now, $"{(IsSafetyDoorTrigged ? "安全门" : "")}{(IsSafetyBeamTrigged ? " 安全光线" : "")}触发中,复位失败", ""); |
| | | return new ProcessResponse(false); |
| | | } |
| | | |
| | | MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice); |
| | | //(invokeDevice as IMotionCard).Reset(); |
| | | |
| | | RaisedAlarm(""); |
| | | MachineState = MachineState.Ready; |
| | |
| | | |
| | | private void FullReset(object state) |
| | | { |
| | | FullReset(null, null, null); |
| | | try |
| | | { |
| | | FullReset(null, null, null); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | ExceptionRaisedInMonitor(ex); |
| | | } |
| | | } |
| | | |
| | | [ProcessMethod("MotionCardOperationConfigCollection", "FullReset", "大复位操作", InvokeType.TestInvoke)] |
| | |
| | | //{ |
| | | // motionCard.Run(opConfig); |
| | | //} |
| | | |
| | | MachineState = MachineState.Resetting; |
| | | MotionCardDefaultRun("FullReset", ref opConfig, ref invokeDevice); |
| | | |
| | | productionList.ForEach(u => u.Dispose()); |
| | |
| | | OnFullResetDone?.Invoke(); |
| | | |
| | | LogAsync(DateTime.Now, "大复位动作完成", ""); |
| | | MachineState = MachineState.Ready; |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | |
| | | WaitHandle = new ManualResetEvent(true), |
| | | WaitResult = true, |
| | | }; |
| | | |
| | | MachineState _machineStateBeforePause = MachineState.Unknown; |
| | | List<MachineState> _statesAllowPause = new List<MachineState>() { MachineState.Running, MachineState.Ready, MachineState.Pause }; |
| | | [ProcessMethod("", "PauseJob", "暂停流程", InvokeType.TestInvoke)] |
| | | public ProcessResponse PauseJob(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | public ProcessResponse SwitchJobStatus(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | { |
| | | if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡暂停动作 |
| | | #endregion |
| | | if (!_statesAllowPause.Contains(MachineState)) |
| | | return new ProcessResponse(-999); |
| | | |
| | | _pauseHandle.WaitHandle.Reset(); |
| | | MotionCardBase motionDevice = sourceDevice as MotionCardBase; |
| | | if (motionDevice == null) |
| | | { |
| | | motionDevice = DeviceCollection.FirstOrDefault(u => u is MotionCardBase) as MotionCardBase; |
| | | } |
| | | |
| | | _pauseHandle.WaitResult = !_pauseHandle.WaitResult; |
| | | if (motionDevice == null) |
| | | throw new ProcessException("未获取板卡设备"); |
| | | |
| | | bool? isToPause = null; //true 暂停 false 继续 |
| | | if (opConfig.InputPara != null && opConfig.InputPara.Count > 0) |
| | | { |
| | | isToPause = opConfig.InputPara[0] == 1; |
| | | } |
| | | |
| | | if (isToPause == null) |
| | | { |
| | | if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡暂停动作 |
| | | motionDevice.StateChange(DeviceState.DSPause); |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Reset(); |
| | | _pauseHandle.WaitResult = true; |
| | | _machineStateBeforePause = MachineState; |
| | | MachineState = MachineState.Pause; |
| | | } |
| | | else if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡恢复动作 |
| | | motionDevice.StateChange(DeviceState.DSOpen); |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Set(); |
| | | _pauseHandle.WaitResult = false; |
| | | MachineState = _machineStateBeforePause; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (isToPause.Value) |
| | | { |
| | | if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡暂停动作 |
| | | motionDevice.StateChange(DeviceState.DSPause); |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Reset(); |
| | | _pauseHandle.WaitResult = true; |
| | | MachineState = MachineState.Pause; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (!_pauseHandle.WaitResult) |
| | | { |
| | | #region 板卡恢复动作 |
| | | motionDevice.StateChange(DeviceState.DSOpen); |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Set(); |
| | | _pauseHandle.WaitResult = false; |
| | | MachineState = _machineStateBeforePause; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return new ProcessResponse(_pauseHandle.WaitResult); |
| | | } |
| | | |
| | | [ProcessMethod("", "ResumeJob", "继续流程", InvokeType.TestInvoke)] |
| | | public ProcessResponse ResumeJob(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) |
| | | { |
| | | if (_pauseHandle.WaitResult) |
| | | if (index_RedLight >= 0) |
| | | { |
| | | #region 板卡恢复动作 |
| | | #endregion |
| | | |
| | | _pauseHandle.WaitHandle.Set(); |
| | | if (outputCtrlCard != null) |
| | | { |
| | | outputCtrlCard.WriteOutput((short)index_RedLight, isOn ? IOValue.TRUE : IOValue.FALSE); |
| | | } |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, "未设置板卡输出设备", ""); |
| | | } |
| | | } |
| | | |
| | | _pauseHandle.WaitResult = !_pauseHandle.WaitResult; |
| | | return new ProcessResponse(_pauseHandle.WaitResult); |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, "红色灯未配置正确输出索引", ""); |
| | | } |
| | | } |
| | | |
| | | [ProcessMethod("MotionCardBase", "SwitchLightRed", "切换指示灯-红", InvokeType.TestInvoke)] |
| | | public ProcessResponse SwitchLightRed(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | public void SwitchLightYellow(bool isOn) |
| | | { |
| | | MotionCardDefaultRun("SwitchLightRed", ref opConfig, ref invokeDevice); |
| | | 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, "黄色灯未配置正确输出索引", ""); |
| | | } |
| | | } |
| | | |
| | | [ProcessMethod("MotionCardBase", "SwitchLightYellow", "切换指示灯-黄", InvokeType.TestInvoke)] |
| | | public ProcessResponse SwitchLightYellow(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, "绿色灯未配置正确输出索引", ""); |
| | | } |
| | | } |
| | | |
| | | [ProcessMethod("MotionCardBase", "SwitchLightGreen", "切换指示灯-绿", InvokeType.TestInvoke)] |
| | | public ProcessResponse SwitchLightGreen(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, "照明灯未配置正确输出索引", ""); |
| | | } |
| | | } |
| | | |
| | | [ProcessMethod("MotionCardBase", "SwitchBeep", "切换蜂鸣器", InvokeType.TestInvoke)] |
| | | public ProcessResponse SwitchBeep(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | public void SwitchBeep(bool isOn) |
| | | { |
| | | return new ProcessResponse(true); |
| | | } |
| | | if (Config.IsBeepBlocked) |
| | | return; |
| | | |
| | | [ProcessMethod("MotionCardBase", "SwitchNormalLight", "切换日光灯", InvokeType.TestInvoke)] |
| | | public ProcessResponse SwitchNormalLight(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | { |
| | | MotionCardDefaultRun("SwitchNormalLight", ref opConfig, ref invokeDevice); |
| | | |
| | | 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, "蜂鸣器未配置正确输出索引", ""); |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | private void MotionCardDefaultRun(string methodCode, ref IOperationConfig opConfig, ref IDevice invokeDevice) |
| | | { |
| | |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | #region 安全门 & 安全光线 |
| | | bool isSafetyDoorTrigged = false; |
| | | bool isSafetyBeamTrigged = false; |
| | | |
| | | public bool IsSafetyDoorTrigged |
| | | { |
| | | get => !Config.IsSafetyDoorBlocked && isSafetyDoorTrigged; |
| | | set => isSafetyDoorTrigged = value; |
| | | } |
| | | public bool IsSafetyBeamTrigged |
| | | { |
| | | get => !Config.IsSafetyBeamBlocked && isSafetyBeamTrigged; |
| | | set => isSafetyBeamTrigged = value; |
| | | } |
| | | |
| | | [ProcessMethod("", "SafetyDoorSignal", "安全门信号监控,正常ON,OFF时报警", InvokeType.TestInvoke)] |
| | | public ProcessResponse SafetyDoorSignal(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | { |
| | | if (opConfig.InputPara == null || opConfig.InputPara.Count == 0) |
| | | throw new ProcessException("安全门监控未配置输入信号"); |
| | | |
| | | IsSafetyDoorTrigged = opConfig.InputPara[0] == 0; |
| | | |
| | | if (IsSafetyDoorTrigged) |
| | | { |
| | | RaisedAlarm("安全门未正常关闭"); |
| | | MachineState = MachineState.Alarm; |
| | | } |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | [ProcessMethod("", "SafetyBeamSignal", "安全光幕信号监控,正常ON,OFF时报警", 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("安全光线被遮挡"); |
| | | MachineState = MachineState.Alarm; |
| | | } |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | #endregion |
| | | } |
| | | } |