using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.Utilities; using CyberX12_RT.Modules.VpwCell; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Persistent.Reservoirs; using MECF.Framework.Common.ProcessCell; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.ToolLayout; using MECF.Framework.RT.Core.Equipments; using PunkHPX8_Core; using PunkHPX8_RT.Devices.PlatingCell; using PunkHPX8_RT.Devices.PowerSupplier; using PunkHPX8_RT.Devices.Reservoir; using PunkHPX8_RT.Devices.Temperature; using PunkHPX8_RT.Modules.Reservoir; using PunkHPX8_RT.Modules.VpwCell; using PunkHPX8_RT.Modules.VpwMain; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Modules.PlatingCell { public class PlatingCellEntity : Entity, IEntity, IModuleEntity { public enum PlatingCellMsg { NONE, Error, ResumeError, Initialize, Manual, Auto, CloseFlowValve, OpenFlowValve, RunRecipe, Abort, Init, CCR, CCRAbort } #region 常量 private const string STRATUS = "Stratus"; private const string AUTO = "Auto"; private const string MANUAL = "Manual"; private const string DISABLED = "Disabled"; private const string ENGINEERING = "Engineering"; private const string PRODUCTION = "Production"; #endregion #region 内部变量 /// /// 持久化数值 /// private PlatingCellPersistentValue _persistentValue; /// /// 当前recipe /// private DepRecipe _currentRecipe; /// /// recipe时间 /// private int _recipeTime; /// /// c&m Initialize routine /// private PlatingCellInitializeRoutine _initializeRoutine; /// /// CCR routine /// private PlatingCellCCRRoutine _platingCellCRRoutine; /// /// Run recipe routine /// private PlatingCellRunRecipeRoutine _runRecipeRoutine; #endregion #region 属性 /// /// 模块名称 /// public ModuleName Module { get; private set; } /// /// 是否Init /// public bool IsInit { get { return fsm.State == (int)PlatingCellState.Init; } } /// /// 是否Idle /// public bool IsIdle { get { return fsm.State == (int)PlatingCellState.Idle; } } /// /// 是否错误 /// public bool IsError { get { return fsm.State == (int)PlatingCellState.Error; } } /// /// 正在忙碌 /// public bool IsBusy { get { return fsm.State == (int)PlatingCellState.Initializing; } } /// /// 化学液 /// public string Chemistry { get { return _currentRecipe != null ? _currentRecipe.Chemistry : ""; } } /// /// 是否禁用 /// public bool IsDisable { get { return _persistentValue == null || _persistentValue.OperatingMode == DISABLED; } } /// /// 自动模式 /// public bool IsAuto { get { return _persistentValue != null && _persistentValue.OperatingMode == AUTO; } } /// /// 自动模式 /// public bool IsManual { get { return _persistentValue != null && _persistentValue.OperatingMode == MANUAL; } } /// /// 是否为工程模式 /// public bool IsEngineering { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == ENGINEERING; } } /// /// 是否为产品模式 /// public bool IsProduction { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == PRODUCTION; } } /// /// 状态机状态 /// public PlatingCellState State { get { return (PlatingCellState)fsm.State; } } /// /// 是否初始化完成 /// public bool IsInitialized { get { return fsm.State >= (int)PlatingCellState.Initialized; } } /// /// Reservoir项 /// private ReservoirItem _reservoirItem; /// /// Wafer信息 /// public WaferInfo WaferInfo { get { return WaferManager.Instance.GetWafer(Module,0); } } /// /// 当前Metal设置的WaferSize /// public int MetalWaferSize { get { return _persistentValue.PlatingCellWaferSize; } } #endregion /// /// 构造函数 /// /// public PlatingCellEntity(ModuleName module) { this.Module = module; InitialFsm(); } /// /// 初始化 /// /// protected override bool Init() { WaferManager.Instance.SubscribeLocation(Module, 1); InitializeRoutine(); InitializeDATA(); InitializeOperation(); InitializeParameter(); return true; } /// /// 初始化参数 /// private void InitializeParameter() { _persistentValue = PlatingCellPersistentManager.Instance.GetPlatingCellPersistentValue(Module.ToString()); if (_persistentValue == null) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module.ToString(), "Persistent Value Object is not exist"); } } /// /// 初始化Routine /// private void InitializeRoutine() { _initializeRoutine = new PlatingCellInitializeRoutine(Module.ToString()); _platingCellCRRoutine = new PlatingCellCCRRoutine(Module.ToString()); } /// /// 初始化DATA /// private void InitializeDATA() { DATA.Subscribe($"{Module}.FsmState", () => ((PlatingCellState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.CurrentRecipe", () => _currentRecipe != null ? _currentRecipe.Ppid : "", SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.TotalTime", () => _recipeTime, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.TimeRemain", () => _recipeTime != 0 && _runRecipeRoutine != null ? (_recipeTime - Math.Round((double)_runRecipeRoutine.ElapsedMilliseconds / 1000, 0)) : 0, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Chemistry", () => _currentRecipe != null ? _currentRecipe.Chemistry : "", SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsInit", () => IsInit, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsIdle", () => IsIdle, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsBusy", () => IsBusy, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsDisable", () => IsDisable, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 初始化Operation /// private void InitializeOperation() { OP.Subscribe($"{Module}.InitializeAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_RESERVOIR, Module.ToString(), (int)PlatingCellMsg.Initialize); }); OP.Subscribe($"{Module}.ManualCCRStart", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_RESERVOIR, Module.ToString(), (int)PlatingCellMsg.CCR); }); OP.Subscribe($"{Module}.ManualCCRStop", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_RESERVOIR, Module.ToString(), (int)PlatingCellMsg.CCRAbort); }); } /// 初始化状态机 /// private void InitialFsm() { fsm = new StateMachine(Module.ToString(), (int)PlatingCellState.Idle, 100); fsm.EnableRepeatedMsg(true); AnyStateTransition(PlatingCellMsg.Error, NullFunc, PlatingCellState.Error); //Initialized Transition(PlatingCellState.Error, PlatingCellMsg.Initialize, InitializeAll, PlatingCellState.Initializing); Transition(PlatingCellState.Init, PlatingCellMsg.Initialize, InitializeAll, PlatingCellState.Initializing); Transition(PlatingCellState.Idle, PlatingCellMsg.Initialize, InitializeAll, PlatingCellState.Initializing); Transition(PlatingCellState.Initializing, FSM_MSG.TIMER, InitializeAllMonitor, PlatingCellState.Idle); //CCR Transition(PlatingCellState.Idle, PlatingCellMsg.CCR, ManualCCRStart, PlatingCellState.CCRing); Transition(PlatingCellState.CCRing, FSM_MSG.TIMER, CCRMonitor, PlatingCellState.Idle); Transition(PlatingCellState.CCRing, PlatingCellMsg.CCRAbort, CCRAbort, PlatingCellState.Init); //Cycle Manual Process Transition(PlatingCellState.Idle, PlatingCellMsg.RunRecipe, CycleManualProcess, PlatingCellState.RunReciping); Transition(PlatingCellState.RunReciping, FSM_MSG.TIMER, CycleManualMonitor, PlatingCellState.Idle); Transition(PlatingCellState.RunReciping, VPWCellMsg.Abort, RunRecipeAbort, PlatingCellState.Idle); //直接进入Idle Transition(PlatingCellState.Initialized, FSM_MSG.TIMER, NullFunc, PlatingCellState.Idle); //Enter Init Transition(PlatingCellState.Idle, PlatingCellMsg.Init, NullFunc, PlatingCellState.Init); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); } /// /// 手动CCR /// /// private bool ManualCCRStart(object[] param) { bool result = _platingCellCRRoutine.Start() == RState.Running; return result; } /// /// CCR 监控 /// /// /// private bool CCRMonitor(object[] param) { RState rsstate = RState.Running; rsstate = _platingCellCRRoutine.Monitor(); if (rsstate == RState.End) { return true; } else if (rsstate == RState.Failed || rsstate == RState.Timeout) { PostMsg(PlatingCellMsg.Error); return false; } return false; } /// /// CCR abort /// /// /// private bool CCRAbort(object[] param) { if(_platingCellCRRoutine.Monitor() == RState.Running) { _platingCellCRRoutine.Abort(); } return true; } /// /// 初始化 /// /// private bool InitializeAll(object[] param) { if (_persistentValue == null) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module.ToString(), "persistent is null"); return false; } if (fsm.State == (int)PlatingCellState.Initializing) { LOG.WriteLog(eEvent.WARN_PLATINGCELL, Module.ToString(), "state is Initializing,cannot do initialize"); return false; } if (!CheckReservoirInitialized()) { LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), "Reservoir is not initialized"); return false; } if (!MetalUsageMointor(Module.ToString())) { return false; } if ("Auto".Equals(_persistentValue.OperatingMode)) { if (!CheckReservoirIsAuto()) { LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), "Reservoir is not in Auto OperationMode"); return false; } } bool result = _initializeRoutine.Start(_persistentValue) == RState.Running; return result; } /// /// 检验Reservoir是否Auto /// /// private bool CheckReservoirIsAuto() { string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString()); ReservoirsPersistentValue reservoirsPersistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(reservoir); if ("Auto".Equals(reservoirsPersistentValue.OperatingMode)) { return true; } return false; } /// /// 检验Reservoir是否Initialized /// /// private bool CheckReservoirInitialized() { string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString()); ReservoirEntity reservoirEntity = Singleton.Instance.GetModule(reservoir); if (reservoirEntity != null) { return reservoirEntity.IsInitialized; } return false; } /// /// 监控 PM Counter Metal用量 /// private bool MetalUsageMointor(string Module) { return true; } /// /// Initialize 监控 /// /// /// private bool InitializeAllMonitor(object[] param) { RState rsstate = RState.Running; rsstate = _initializeRoutine.Monitor(); if (rsstate == RState.End) { return true; } else if (rsstate == RState.Failed || rsstate == RState.Timeout) { PostMsg(PlatingCellMsg.Error); return false; } return false; } /// /// EnterInit /// public void EnterInit() { if ((PlatingCellState)fsm.State != PlatingCellState.Idle) return; else { CheckToPostMessage(eEvent.ERR_PLATINGCELL, Module.ToString(), (int)PlatingCellMsg.Init); } } #region cycle manual process /// /// process /// /// /// private bool CycleManualProcess(object[] param) { bool result = _runRecipeRoutine.Start(param) == RState.Running; if (result) { } return result; } /// /// 监控 /// /// /// private bool CycleManualMonitor(object[] param) { RState state = _runRecipeRoutine.Monitor(); if (state == RState.Failed || state == RState.Timeout) { return false; } bool result = state == RState.End; if (result) { } return result; } /// /// 中止 /// /// /// private bool RunRecipeAbort(object[] param) { _runRecipeRoutine.Abort(); VpwMainEntity vpwMainEntity = Singleton.Instance.GetModule("VPWMain1"); if (vpwMainEntity != null) { //把main的状态置为暂停 vpwMainEntity.PostMsg(VPWMainMsg.Abort); } return true; } #endregion public bool Check(int msg, out string reason, params object[] args) { reason = ""; return true; } public bool CheckAcked(int msg) { throw new NotImplementedException(); } public int Invoke(string function, params object[] args) { switch (function) { case "HomeAll": if (IsIdle) { return (int)FSM_MSG.NONE; } if (CheckToPostMessage(eEvent.ERR_PLATINGCELL, Module.ToString(), (int)PlatingCellMsg.Initialize)) { return (int)PlatingCellMsg.Initialize; } else { return (int)FSM_MSG.NONE; } } return (int)FSM_MSG.NONE; } } }