using Aitex.Core.RT.Device;
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.Utilities;
using MECF.Framework.Common.RecipeCenter;
using CyberX8_Core;
using CyberX8_RT.Devices.LinMot;
using CyberX8_RT.Devices.Prewet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
using MECF.Framework.Common.CommonData.Prewet;
using static CyberX8_RT.Modules.Prewet.PrewetKeepWetStateMachine;
namespace CyberX8_RT.Modules.Prewet
{
public class PrewetProcessStateMachine : Entity, IEntity
{
#region 内部变量
///
/// 模块名称
///
private string _module;
///
/// prewet设备
///
private PrewetDevice _prewetDevice;
///
/// linmot axis
///
private LinMotAxis _linMotAxis;
///
/// Prewet recipe
///
private PwtRecipe _recipe;
#endregion
#region 属性
///
/// 状态
///
public string State { get { return ((PrewetProcessState)fsm.State).ToString(); } }
#endregion
///
/// 构造函数
///
///
public PrewetProcessStateMachine(string module,LinMotAxis linMotAxis)
{
_module = module;
_prewetDevice = DEVICE.GetDevice(module);
_linMotAxis = linMotAxis;
this.fsm = new StateMachine($"{module}_ProcessStateMachine", (int)PrewetProcessState.Idle, 10);
fsm.EnableRepeatedMsg(true);
AnyStateTransition(PrewetProcessMsg.Error, EnterError, PrewetProcessState.Error);
Transition(PrewetProcessState.Error, PrewetProcessState.Process_Start, EnterProcessStartStatus, PrewetProcessState.Process_Start);
Transition(PrewetProcessState.Idle, PrewetProcessMsg.ProcessStart, EnterProcessStartStatus, PrewetProcessState.Process_Start);
Transition(PrewetProcessState.Process_Start,FSM_MSG.TIMER, NullFunc, PrewetProcessState.Process_StartScanning);
Transition(PrewetProcessState.Process_StartScanning,FSM_MSG.TIMER, ProcessStartScan, WaitProcessStartStatus, PrewetProcessState.Process_WaitFirstScanComplete);
Transition(PrewetProcessState.Process_WaitFirstScanComplete, FSM_MSG.TIMER, StartScan, PrewetProcessState.Process_WaitScanComplete);
Transition(PrewetProcessState.Process_WaitScanComplete, FSM_MSG.TIMER, WaitScanComplete, PrewetProcessState.Process_Complete);
Transition(PrewetProcessState.Process_Complete, FSM_MSG.TIMER, ProcessComplete, PrewetProcessState.Idle);
EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
}
///
/// 进入启动状态
///
///
private bool EnterProcessStartStatus(object param)
{
object[] objects = param as object[];
PwtRecipe pwtRecipe = (PwtRecipe)objects[0];
if(pwtRecipe == null)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "recipe is null error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
_recipe = pwtRecipe;
return true;
}
///
/// 进入Error状态
///
///
///
private bool EnterError(object param)
{
if(_linMotAxis.Status==RState.Running)
{
_linMotAxis.AbortCurrentRoutine();
}
if(_prewetDevice.Status==RState.Running)
{
_prewetDevice.AbortCurrentRoutine();
}
return true;
}
#region process
///
/// Process Start Scan
///
///
private bool ProcessStartScan(object param)
{
bool result = _linMotAxis.ResetOperation("", false);
if (!result)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "reset linmot error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
_prewetDevice.PrewetPumpData.PumpSpeedAuto = true;
//更新Pump status状态
string statusContent = _prewetDevice.PrewetPumpData.PumpStatus ? "On" : "Off";
_prewetDevice.PrewetPumpData.PumpModel = "Auto";
_prewetDevice.PrewetPumpData.PumpStatusContent = $"{_prewetDevice.PrewetPumpData.PumpModel}: {statusContent}";
result = _prewetDevice.PumpSpeed();
if(!result)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump speed error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
bool pumpEnableResult = _prewetDevice.PumpEnableOperation("", null);
if (!pumpEnableResult)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump enable error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
return true;
}
///
/// 等待start process状态
///
///
private bool WaitProcessStartStatus(object param)
{
if(_prewetDevice.Status==RState.Failed)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "prewet device status is error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
if (_linMotAxis.Status == RState.Failed)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "linmot status is error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
if (_prewetDevice.Status == RState.End && _linMotAxis.Status == RState.End)
{
return true;
}
return false;
}
///
/// 开始Scan
///
///
///
private bool StartScan(object param)
{
if (!_linMotAxis.IsHomed)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "limot is not ready");
PostMsg(PrewetProcessMsg.Error);
return false;
}
if(!_prewetDevice.PrewetPumpData.PumpStatus)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump status if off");
PostMsg(PrewetProcessMsg.Error);
return false;
}
bool result = _linMotAxis.StartPosition("", new object[] { _recipe.NumberOfScans });
if(!result)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "linmot start scan error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
return true;
}
///
/// 等待Scan结束
///
///
///
private bool WaitScanComplete(object param)
{
if (_prewetDevice.PrewetPumpData.PumpFlowData.IsWarning)
{
LOG.WriteLog(eEvent.WARN_PREWET, _module, $"pump flow status {_prewetDevice.PrewetPumpData.PumpFlowData.Value} is in warning");
}
if (_prewetDevice.PrewetPumpData.PumpFlowData.IsError)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, $"pump flow status {_prewetDevice.PrewetPumpData.PumpFlowData.Value} is in error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
if (_prewetDevice.PrewetPumpData.PumpPressureData.IsWarning)
{
LOG.WriteLog(eEvent.WARN_PREWET, _module, $"pump pressure status is {_prewetDevice.PrewetPumpData.PumpPressureData.Value} in warning");
}
if (_prewetDevice.PrewetPumpData.PumpPressureData.IsError)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, $"pump pressure status {_prewetDevice.PrewetPumpData.PumpPressureData.Value} is in error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
//linmot完成一次scan
if (_linMotAxis.Status == RState.End)
{
return true;
}
if (_linMotAxis.Status == RState.Failed)
{
PostMsg(PrewetProcessMsg.Error);
return false;
}
return false;
}
///
/// Process scan完成
///
///
///
private bool ProcessComplete(object param)
{
bool result = _prewetDevice.PumpDisableOperation("pump disable", null);
if (!result)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump disable error");
PostMsg(PrewetKeepWetMsg.Error);
return false;
}
result = _linMotAxis.SwitchOff();
if (!result)
{
LOG.WriteLog(eEvent.ERR_PREWET, _module, "linmot disable error");
PostMsg(PrewetProcessMsg.Error);
return false;
}
return true;
}
#endregion
public bool Check(int msg, out string reason, params object[] args)
{
reason = "";
return true;
}
public enum PrewetProcessState
{
Error,
Idle,
Process_Start,
Process_StartScanning,
Process_WaitFirstScanComplete,
Process_WaitScanComplete,
Process_Complete
}
public enum PrewetProcessMsg
{
Error,
ProcessStart
}
}
}