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 || !(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);
}
}
}
#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
}
}