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.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; const int FULLRESETTIME = 5; object machineStateLock = new object(); MachineState machineState = MachineState.Unknown; public MachineState MachineState { get => machineState; set { machineState = value; 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, "未配置板卡设备", ""); } } [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 (IsSafetyBeamTrigged || IsSafetyDoorTrigged) { LogAsync(DateTime.Now, $"{(IsSafetyDoorTrigged ? "安全门" : "")}{(IsSafetyBeamTrigged ? " 安全光线" : "")}触发中,复位失败", ""); return new ProcessResponse(false); } MotionCardDefaultRun("Reset", ref opConfig, ref invokeDevice); (invokeDevice as MotionCardBase).ResetAlarm(); RaisedAlarm(""); MachineState = MachineState.Ready; if (ResetTimer == null) { ResetTimer = new Timer(FullReset, null, -1, -1); } 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, "普通复位动作完成", ""); 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 (opConfig == null) //{ // var monitorSet = Config.MonitorSetCollection.FirstOrDefault(u => u.MethodCode == "FullReset"); // 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) //{ // motionCard.Run(opConfig); //} MachineState = MachineState.Resetting; MotionCardDefaultRun("FullReset", ref opConfig, ref invokeDevice); productionList.ForEach(u => u.Dispose()); productionList.Clear(); OnFullResetDone?.Invoke(); LogAsync(DateTime.Now, "大复位动作完成", ""); MachineState = MachineState.Ready; return new ProcessResponse(true); } /// /// 暂停标志 /// WaitHandle 暂停句柄 默认为非阻塞 可执行 /// WaitResult 暂停标志 true 正常执行 false 暂停中 /// ManualWaitConfirm _pauseHandle = new ManualWaitConfirm() { WaitHandle = new ManualResetEvent(true), WaitResult = true, }; MachineState _machineStateBeforePause = MachineState.Unknown; List _statesAllowPause = new List() { 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 != null && opConfig.InputPara.Count > 0) { isToPause = opConfig.InputPara[0] == 1; } 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; } } 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 = _machineStateBeforePause; } } } return new ProcessResponse(_pauseHandle.WaitResult); } ////[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) { 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); } } } #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 } }