Browse Source

新增RecipeHold/RecipeRelease/RecipeAbort/RecipeStepSkip/RecipeJump/CJPusms等事件上报

jiangjy 1 week ago
parent
commit
abc7a0c645

+ 10 - 0
FrameworkLocal/Common/FAServices/DataVariables.cs

@@ -99,6 +99,10 @@ namespace MECF.Framework.Common.FAServices
         public const string SubRecipeStepNumber = "SubRecipeStepNumber";
         public const string IsInSubProcessing = "IsInSubProcessing";
         public const string PJId = "PJId";
+        public const string CallRecipeID = "CallRecipeID";
+        public const string StepId = "StepId";
+        public const string NewRecipeStepNumber = "NewRecipeStepNumber";
+        public const string RecID = "RecID";
 
 
         #endregion
@@ -199,6 +203,9 @@ namespace MECF.Framework.Common.FAServices
             ProcessLotIdList = 3521,
             PJId = 3522,
 
+            CallRecipeID = 3523,
+            StepId = 3524,
+            NewRecipeStepNumber = 3525,
 
 
             #endregion
@@ -287,6 +294,9 @@ namespace MECF.Framework.Common.FAServices
             {BufferCapacitiyList, new VIDItem() {Name = BufferCapacitiyList, Index = (int) DataName.BufferCapacitiyList,DataType = "List",Description = "List of BufferCapacitiy .\r\nL, n\r\nL, 3\r\n<BufferCapacitiy> \r\n<TimeIn>\r\n<TimeOut>"}},
             {BufferMaterialInfo, new VIDItem() {Name = BufferMaterialInfo, Index = (int) DataName.BufferMaterialInfo,DataType = "List",Description = "List of BufferMaterial.\r\nL, n\r\nL, 3\r\n<BufferMaterial> \r\n<TimeIn>\r\n<TimeOut>"}},
             {PPStepChange, new VIDItem() {Name = PPStepChange, Index = (int) DataName.PPStepChange,DataType = "String",Description = "BoatThickness"}},
+            {CallRecipeID, new VIDItem() {Name = CallRecipeID, Index = (int) DataName.CallRecipeID,DataType = "String",Description = "CallRecipeID"}},
+            {StepId, new VIDItem() {Name = StepId, Index = (int) DataName.StepId,DataType = "String",Description = "StepId"}},
+            {NewRecipeStepNumber, new VIDItem() {Name = NewRecipeStepNumber, Index = (int) DataName.NewRecipeStepNumber,DataType = "String",Description = "NewRecipeStepNumber"}},
 
             {ProcessWaferIdList, new VIDItem() {Name = ProcessWaferIdList, Index = (int) DataName.ProcessWaferIdList,DataType = "List",Description = "List of process waferID.\r\nL, n\r\nL, 3\r\n<waferID> \r\n<TimeIn>\r\n<TimeOut>"}},
             {ProcessLotIdList, new VIDItem() {Name = ProcessLotIdList, Index = (int) DataName.ProcessLotIdList,DataType = "List",Description = "List of process LotId.\r\nL, n\r\nL, 3\r\n<ProcessLotIdList> \r\n<TimeIn>\r\n<TimeOut>"}},

+ 49 - 0
FrameworkLocal/Common/FAServices/UniversalEvents.cs

@@ -58,6 +58,18 @@ namespace MECF.Framework.Common.FAServices
         public const string RecipeStepStart = "RecipeStepStart";
         public const string RecipeStepEnd = "RecipeStepEnd";
         public const string RecipeFailed = "RecipeFailed";
+
+        public const string RecipeStop = "RecipeStop";
+        public const string RecipeHold = "RecipeHold";
+        public const string RecipeRelease = "RecipeRelease";
+        public const string RecipeJumpStep = "RecipeJumpStep";
+        public const string RecipeStepSkip = "RecipeStepSkip";
+        public const string RecipeJumpEnd = "RecipeJumpEnd";
+        public const string RecipeAbort = "RecipeAbort";
+        public const string CallAlarmRecipe = "CallAlarmRecipe";
+        public const string CallAbortRecipe = "CallAbortRecipe";
+        public const string RunResetRecipe = "RunResetRecipe";
+
         public const string CarrierInEnd = "CarrierInEnd";
         public const string CarrierInStart = "CarrierInStart";
         public const string CarrierOutStart = "CarrierOutStart";
@@ -128,11 +140,18 @@ namespace MECF.Framework.Common.FAServices
             RecipeStepEnd = 2003,
             RecipeFailed = 2004,
 
+
+
+
+
+
             ChargeStart = 2010,
             ChargeEnd = 2011,
             DischargeStart = 2012,
             DischargeEnd = 2013,
 
+
+
             BatchLocOccupied = 2020,
             BatchLocUnOccupied = 2021,
             SideDummyStateAlarm = 2022,
@@ -143,6 +162,19 @@ namespace MECF.Framework.Common.FAServices
             CarrierOutEnd = 2027,
             SideDummyStateWarning = 2028,
             ExtraDummyStateWarning = 2029,
+
+
+            RecipeHold = 2040,
+            RecipeRelease = 2041,
+            RecipeStop = 2042,
+            RecipeJumpStep = 2043,
+            RecipeAbort = 2044,
+            RecipeSkip = 2045,
+            RecipeJumpEnd = 2046,
+            CallAlarmRecipe = 2047,
+            CallAbortRecipe = 2048,
+            RunResetRecipe = 2049,
+            RecipeStepSkip = 2050,
         }
 
         /// <summary>
@@ -212,6 +244,9 @@ namespace MECF.Framework.Common.FAServices
             {RecipeStepEnd, new VIDItem() {Name = RecipeStepEnd, Index = (int)EventName.RecipeStepEnd, LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.PortID,(int)DataVariables.DataName.StationName, (int)DataVariables.DataName.RecipeStepNumber, (int)DataVariables.DataName.SlotID}}},
             {RecipeFailed, new VIDItem() {Name = RecipeFailed, Index = (int)EventName.RecipeFailed,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.PortID,(int)DataVariables.DataName.StationName,(int)DataVariables.DataName.SlotID}}},
 
+        
+
+
             {ChargeStart, new VIDItem() {Name = ChargeStart, Index = (int)EventName.ChargeStart,  LinkableVid = new[] {(int)DataVariables.DataName.PRJobID, (int)DataVariables.DataName.Clock}}},
             {ChargeEnd, new VIDItem() {Name = ChargeEnd, Index = (int)EventName.ChargeEnd,  LinkableVid = new[] {(int)DataVariables.DataName.PRJobID, (int)DataVariables.DataName.Clock, (int)DataVariables.DataName.BoatSlotMapList}}},
             {DischargeStart, new VIDItem() {Name = DischargeStart, Index = (int)EventName.DischargeStart,  LinkableVid = new[] {(int)DataVariables.DataName.PRJobID, (int)DataVariables.DataName.Clock, (int)DataVariables.DataName.BoatSlotMapList}}},
@@ -248,6 +283,20 @@ namespace MECF.Framework.Common.FAServices
                 (int)DataVariables.DataName.EventName,
             }}},
 
+            {RecipeHold, new VIDItem() {Name = RecipeHold, Index = (int)EventName.RecipeHold,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.RecipeStepNumber}}},
+            {RecipeStop, new VIDItem() {Name = RecipeStop, Index = (int)EventName.RecipeStop,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber}}},
+            {RecipeRelease, new VIDItem() {Name = RecipeRelease, Index = (int)EventName.RecipeRelease,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber}}},
+            {RecipeStepSkip, new VIDItem() {Name = RecipeStepSkip, Index = (int)EventName.RecipeStepSkip,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber}}},
+
+            {RecipeJumpStep, new VIDItem() {Name = RecipeJumpStep, Index = (int)EventName.RecipeJumpStep,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber, (int)DataVariables.DataName.StepId}}},
+            {RecipeAbort, new VIDItem() {Name = RecipeAbort, Index = (int)EventName.RecipeAbort,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber}}},
+            {RecipeJumpEnd, new VIDItem() {Name = RecipeJumpEnd, Index = (int)EventName.RecipeJumpEnd,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber, (int)DataVariables.DataName.StepId}}},
+
+            {CallAlarmRecipe, new VIDItem() {Name = CallAlarmRecipe, Index = (int)EventName.CallAlarmRecipe,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber, (int)DataVariables.DataName.CallRecipeID}}},
+            {CallAbortRecipe, new VIDItem() {Name = CallAbortRecipe, Index = (int)EventName.CallAbortRecipe,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber, (int)DataVariables.DataName.CallRecipeID}}},
+            {RunResetRecipe, new VIDItem() {Name = RunResetRecipe, Index = (int)EventName.RunResetRecipe,  LinkableVid = new[] {(int)DataVariables.DataName.RecipeID,(int)DataVariables.DataName.NewRecipeStepNumber, (int)DataVariables.DataName.CallRecipeID }}},
+
+
         };
 
     }

+ 13 - 3
Furnace/FurnaceRT/Equipments/Jobs/AutoTransfer.cs

@@ -797,7 +797,11 @@ namespace FurnaceRT.Equipments.Jobs
                 if (pj.ControlJobName == cj.Name)
                 {
                     if (pj.State == EnumProcessJobState.Processing)
+                    {
                         _faCallback.JobAborted(cj, pj);
+                        _faCallback.CJAbort(cj, pj);
+
+                    }
                     pj.SetState(EnumProcessJobState.Aborting);
                     if (pj.ProcessingState == EnumProcessingState.Charging || pj.ProcessingState == EnumProcessingState.Discharging)
                     {
@@ -855,7 +859,12 @@ namespace FurnaceRT.Equipments.Jobs
                 if (pj.ControlJobName == cj.Name)
                 {
                     if (pj.State == EnumProcessJobState.Processing)
+                    {
+
+                        _faCallback.CJResume(cj, GetFirstProcessJob(cj));
                         _faCallback.JobResumed(cj, pj);
+
+                    }
                 }
             }
         }
@@ -909,6 +918,7 @@ namespace FurnaceRT.Equipments.Jobs
                 {
                     cj.SetState(EnumControlJobState.Paused);
 
+                    _faCallback.CJPaused(cj, GetFirstProcessJob(cj));
                     _faCallback.JobPaused(cj, GetFirstProcessJob(cj));
                 }
             }
@@ -1522,7 +1532,7 @@ namespace FurnaceRT.Equipments.Jobs
             var laIsNeedXxygenPressure = pmModule.CheckLAIsNeedOxygenPressure(pj.N2PurgeModeStr);
             if (laIsNeedXxygenPressure)
             {
-             
+
                 if (SC.ContainsItem("PM1.RecipeRelevancyN2Purge") && SC.GetValue<bool>("PM1.RecipeRelevancyN2Purge") && SC.ContainsItem("PM1.SelectN2PurgeMode"))
                 {
                     var setValue = pmModule.GetN2PurgeModeEnumByStr(pj.N2PurgeModeStr);
@@ -1699,7 +1709,7 @@ namespace FurnaceRT.Equipments.Jobs
                             {
                                 if (st.Load(CheckFimsIsNeedOxygenPressure, N2PurgeModeEnum.WaferCharge.ToString()))
                                 {
-                                    
+
 
                                     _fimsCheckOxDensityDict[st.Module.ToString()].Item1.Restart();
                                     LOG.Info($"FIMS={st.Module} , FIMS N2PurgeConfig={waferChargeFIMSN2purgeConfig},Recipe N2purge Set={pj.N2PurgeModeStr},Currect N2Purge={lACurrectN2purgeMode},pjStatus:{pj.ProcessingState},wait WaferCharge。A");
@@ -6730,7 +6740,7 @@ namespace FurnaceRT.Equipments.Jobs
                             var laIsNeedXxygenPressure = pmModule.CheckLAIsNeedOxygenPressure(pj.N2PurgeModeStr);
                             if (laIsNeedXxygenPressure)
                             {
-                              
+
                                 if (SC.ContainsItem("PM1.RecipeRelevancyN2Purge") && SC.GetValue<bool>("PM1.RecipeRelevancyN2Purge") && SC.ContainsItem("PM1.SelectN2PurgeMode"))
                                 {
                                     var setValue = pmModule.GetN2PurgeModeEnumByStr(pj.N2PurgeModeStr);

+ 14 - 2
Furnace/FurnaceRT/Equipments/PMs/PMAlarmCondition.cs

@@ -17,6 +17,7 @@ using MECF.Framework.Common.CommonData.EnumData;
 using MECF.Framework.Common.Device.Bases;
 using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.Event;
+using MECF.Framework.Common.FAServices;
 using MECF.Framework.Common.OperationCenter;
 using MECF.Framework.Common.Tolerance;
 using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
@@ -982,6 +983,8 @@ namespace FurnaceRT.Equipments.PMs
                     if (!string.IsNullOrEmpty(sensorName))
                         log = $"{log} ,sensorName={sensorName}";
 
+
+                    _processRoutine.FACallBack(UniversalEvents.RunResetRecipe, Module, RecipeRunningInfo.RecipeName, RecipeRunningInfo.StepNumber.ToString(), recipe);
                     LOG.Write(log);
                     break;
                 case "End":
@@ -992,6 +995,9 @@ namespace FurnaceRT.Equipments.PMs
                     {
                         //因为要跳到执行最后一步,所以stepNumber需要减一
                         _processRoutine.JumpCurrentRecipeStep(RecipeRunningInfo.RecipeStepList.Count - 1, RecipeRunningInfo.RecipeStepList[RecipeRunningInfo.RecipeStepList.Count - 1].StepName);
+
+                        _processRoutine.FACallBack(UniversalEvents.RecipeJumpEnd, Module, RecipeRunningInfo.RecipeName, RecipeRunningInfo.StepNumber.ToString(), $"{RecipeRunningInfo.RecipeStepList.Count - 1}");
+
                     }
                     else
                     {
@@ -1011,6 +1017,8 @@ namespace FurnaceRT.Equipments.PMs
                     if (!string.IsNullOrEmpty(sensorName))
                         log = $"{log} ,sensorName={sensorName}";
 
+
+
                     LOG.Write(log);
                     break;
                 case "Hold":
@@ -1018,9 +1026,11 @@ namespace FurnaceRT.Equipments.PMs
                         break;
                     _isAlarmConditionHasRecipeCommand = true;
                     _processRoutine.PauseRecipe();
-                     log = $"Alarm condition: command={command}";
+                    log = $"Alarm condition: command={command}";
                     if (!string.IsNullOrEmpty(sensorName))
                         log = $"{log} ,sensorName={sensorName}";
+
+
                     LOG.Write(log);
                     break;
                 case "Monitor"://蜂鸣器不需要响
@@ -1056,6 +1066,7 @@ namespace FurnaceRT.Equipments.PMs
                             if (jumpStepNumber > 0)
                             {
                                 _processRoutine.JumpCurrentRecipeStep(jumpStepNumber, stepName);
+
                             }
                         }
                         else
@@ -1091,6 +1102,7 @@ namespace FurnaceRT.Equipments.PMs
                             recipeType = "Alarm";
                             recipeTable = paras[0].Replace("CALL", "").Replace(" ", "").Replace(":", "").Replace(":", "");
                             CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType, recipeTable);
+                            _processRoutine.FACallBack(UniversalEvents.CallAlarmRecipe, Module, RecipeRunningInfo.RecipeName, RecipeRunningInfo.StepNumber.ToString(), $"{recipe}");
 
                             LOG.Write($"Alarm condition: command={command} recipe={recipe}");
                         }
@@ -1108,7 +1120,7 @@ namespace FurnaceRT.Equipments.PMs
                             recipeType = "Abort";
                             recipeTable = paras[0].Replace("ABORT", "").Replace(" ", "").Replace(":", "").Replace(":", "");
                             CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType, recipeTable);
-
+                            _processRoutine.FACallBack(UniversalEvents.CallAbortRecipe, Module, RecipeRunningInfo.RecipeName, RecipeRunningInfo.StepNumber.ToString(), $"{recipe}");
                             LOG.Write($"Alarm condition: command={command} recipe={recipe}");
                         }
                     }

+ 11 - 2
Furnace/FurnaceRT/Equipments/PMs/PMModule.cs

@@ -45,6 +45,7 @@ using System.Runtime.Remoting.Metadata.W3cXsd2001;
 using FurnaceRT.Equipments.Schedulers;
 using FabConnect.SecsGemInterface.Common;
 using MECF.Framework.Common.FAServices;
+using MECF.Framework.FA.Core.FAInterface;
 
 namespace FurnaceRT.Equipments.PMs
 {
@@ -1337,6 +1338,8 @@ namespace FurnaceRT.Equipments.PMs
                 {
                     PostMsg(MSG.Error);
                     ExecuteAbortRecipeFailAlarm.Set($"Load abort recipe {recipeName} failed, {reason}");
+                    _processRoutine.FACallBack(UniversalEvents.RecipeAbort, Module, RecipeRunningInfo.RecipeName, _processRoutine._currentStepNumber.ToString());
+
                     return false;
                 }
             }
@@ -1352,6 +1355,8 @@ namespace FurnaceRT.Equipments.PMs
                     if (!RecipeParser.ParseTables(_recipeRunningInfo.Head.AbortRecipe, Module, out var recipeData, out reason, "Abort"))
                     {
                         ExecuteAbortRecipeFailAlarm.Set($"Load abort recipe {recipeName} failed, {reason}");
+                        _processRoutine.FACallBack(UniversalEvents.RecipeAbort, Module, RecipeRunningInfo.RecipeName, _processRoutine._currentStepNumber.ToString());
+
                         return false;
                     }
                     else
@@ -1368,6 +1373,8 @@ namespace FurnaceRT.Equipments.PMs
             {
                 if (!RecipeParser.ParseTables(SC.GetStringValue("System.Recipe.Abort Recipe"), Module, out var recipeData, out reason, "Abort"))
                 {
+                    _processRoutine.FACallBack(UniversalEvents.RecipeAbort, Module, RecipeRunningInfo.RecipeName, _processRoutine._currentStepNumber.ToString());
+
                     ExecuteAbortRecipeFailAlarm.Set($"Load abort recipe {recipeName} failed, {reason}");
                     return false;
                 }
@@ -1378,6 +1385,8 @@ namespace FurnaceRT.Equipments.PMs
                 }
 
             }
+            _processRoutine.FACallBack(UniversalEvents.RecipeAbort, Module, RecipeRunningInfo.RecipeName, _processRoutine._currentStepNumber.ToString());
+
             RecipeExecEntryEnumValue = RecipeExecEntryEnum.AbortRecipeTrigger;
             CheckToPostMessage((int)MSG.RunOtherRecipe, recipeName, recipeType, recipeTable);
             return true;
@@ -1428,7 +1437,7 @@ namespace FurnaceRT.Equipments.PMs
                     WaferManager.Instance.UpdateWaferProcessStatus(ModuleHelper.Converter(Module), i, EnumWaferProcessStatus.Failed);
                 }
 
-                _processRoutine.Abort();
+                //    _processRoutine.Abort();
 
                 _postprocessRoutine.Abort();
 
@@ -1781,7 +1790,7 @@ namespace FurnaceRT.Equipments.PMs
             DATA.Subscribe($"ProcessRecipeStepName", () => IsProcessing ? _processRecipeStepName : "");
             DATA.Subscribe($"SubRecipeStepName", () => _subRecipeStepName);
             DATA.Subscribe($"SubRecipeStepNumber", () => _subRecipeStepNumber);
-            DATA.Subscribe($"IsInSubProcessing", () => _isInSubProcessing);
+            //DATA.Subscribe($"IsInSubProcessing", () => _isInSubProcessing);
         }
         #endregion
         #region 

+ 47 - 2
Furnace/FurnaceRT/Equipments/PMs/RecipeExecutions/Process.cs

@@ -18,6 +18,8 @@ using MECF.Framework.Common.DataCenter;
 using System.Runtime.Remoting.Metadata.W3cXsd2001;
 using FurnaceRT.Equipments.Systems;
 using MECF.Framework.Common.CommonData.EnumData;
+using MECF.Framework.Common.FAServices;
+using System.Threading.Tasks;
 
 namespace FurnaceRT.Equipments.PMs.RecipeExecutions
 {
@@ -110,7 +112,7 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
             }
         }
 
-
+        public string FDCRecipeStep { get; set; }
         public int CurrentLoopCount
         {
             get;
@@ -786,9 +788,13 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
                             if (PMModule.IsPaused)
                             {
                                 _state = RecipeRunningState.Paused;
+                                var step = IsSubReciep ? _currentSubRecipeStepNumber + 1 : _currentStepNumber;
+
+                                _faCallback.RecipeHold(PMModule.Module, PMModule.RecipeRunningInfo.RecipeName, step.ToString());
                                 break;
                             }
 
+
                             break;
 
                         case RecipeRunningState.RecipeCompleted:
@@ -1136,7 +1142,9 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
 
             _state = RecipeRunningState.RecipeCompleted;//暂时这么做
             //更新步次结束时间
-            _dbCallback.RecipeStepEnd(PMModule.RecipeRunningInfo.InnerId.ToString(), IsSubReciep ? _currentSubRecipeStepNumber + 1 : _currentStepNumber, _fdc.DataList, SC.GetStringValue("PM1.TempCorrection"), SC.GetStringValue("PM1.Heater.PID"));
+            var step = IsSubReciep ? _currentSubRecipeStepNumber + 1 : _currentStepNumber;
+            _dbCallback.RecipeStepEnd(PMModule.RecipeRunningInfo.InnerId.ToString(), step, _fdc.DataList, SC.GetStringValue("PM1.TempCorrection"), SC.GetStringValue("PM1.Heater.PID"));
+
             return;//暂时这么做
 
             //_totalElpasedTime = 0;
@@ -1197,6 +1205,12 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
         {
             PMModule.IsPaused = false;
             ContinueAction = RecipeContinueMode.StepContinue;
+            var step = IsSubReciep ? _currentSubRecipeStepNumber + 1 : _currentStepNumber;
+
+            Task.Delay(300).ContinueWith((a) =>
+            {
+                _faCallback.RecipeRelease(PMModule.Module, PMModule.RecipeRunningInfo.RecipeName, step.ToString());
+            });
         }
 
 
@@ -1219,10 +1233,13 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
             if (IsSubReciep)
             {
                 ResetLoop(PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber].SubRecipeSteps, _currentSubRecipeStepNumber);
+                _faCallback.RecipeStepSkip(PMModule.Module, PMModule.RecipeRunningInfo.RecipeName, _currentSubRecipeStepNumber.ToString());
             }
             else
             {
                 ResetLoop(PMModule.RecipeRunningInfo.RecipeStepList, _currentStepNumber);
+                _faCallback.RecipeStepSkip(PMModule.Module, PMModule.RecipeRunningInfo.RecipeName, _currentStepNumber.ToString());
+
             }
         }
 
@@ -1266,10 +1283,38 @@ namespace FurnaceRT.Equipments.PMs.RecipeExecutions
         {
             JumpCurrentRecipeStep(_currentStepNumber - 1, PMModule.RecipeRunningInfo.RecipeStepList[_currentStepNumber - 1].StepName);
         }
+        public void FACallBack(string recipeAction, string module, string recipeName, string recipeStep, string jumpStpeId = "", string otherRecipeName = "")
+        {
+            if (recipeAction == UniversalEvents.RecipeAbort)
+            {
+                _faCallback.RecipeAbort(module, recipeName, recipeStep);
+            }
+            if (recipeAction == UniversalEvents.RecipeJumpStep)
+            {
+                _faCallback.RecipeJumpStep(module, recipeName, recipeStep, jumpStpeId);
+            }
+            if (recipeAction == UniversalEvents.RecipeJumpEnd)
+            {
+                _faCallback.RecipeJumpEnd(module, recipeName, recipeStep, jumpStpeId);
+            }
+            if (recipeAction == UniversalEvents.CallAlarmRecipe)
+            {
+                _faCallback.RecipeCallAlarmRecipe(module, recipeName, recipeStep, otherRecipeName);
+            }
+            if (recipeAction == UniversalEvents.CallAbortRecipe)
+            {
+                _faCallback.RecipeCallAbortRecipe(module, recipeName, recipeStep, otherRecipeName);
+            }
+            if (recipeAction == UniversalEvents.RunResetRecipe)
+            {
+                _faCallback.RecipeRunResetRecipe(module, recipeName, recipeStep, otherRecipeName);
+            }
+        }
         public void JumpCurrentRecipeStep(int stepNumber, string stepName, bool isAlarmConditionCall = false)
         {
             PMModule.StopLeakCheckTimer();
             LOG.Write($"Jump to step stepNumber={stepNumber} stepName={stepName}, currentStepNumber={_currentStepNumber}");
+            _faCallback.RecipeJumpStep(PMModule.Module, PMModule.RecipeRunningInfo.RecipeName, stepNumber.ToString(), _currentStepNumber.ToString());
             if (_state == RecipeRunningState.ConditionWait || _state == RecipeRunningState.TimeWait ||
                 _state == RecipeRunningState.Paused || _state == RecipeRunningState.ExecStep)
             {

+ 93 - 0
Furnace/FurnaceRT/Equipments/PMs/RecipeFACallback.cs

@@ -10,6 +10,8 @@ using FurnaceRT.FAs;
 using Aitex.Core.Common;
 using FabConnect.SecsGemInterface.Common;
 using MECF.Framework.Common.SubstrateTrackings;
+using MECF.Framework.Common.FAServices;
+using static MECF.Framework.Common.FAServices.DataVariables;
 
 namespace FurnaceRT.Equipments.PMs
 {
@@ -211,6 +213,97 @@ namespace FurnaceRT.Equipments.PMs
                 {DVIDName.RecipeStepNumber,  (stepNumber+1).ToString()},
             });
         }
+
+
+        public void RecipeHold(string module, string recipeName, string recipeStep)
+        {
+            EV.Notify(UniversalEvents.RecipeHold, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+                {"RecID",  recipeName},
+            });
+        }
+        public void RecipeRelease(string module, string recipeName, string recipeStep)
+        {
+            EV.Notify(UniversalEvents.RecipeRelease, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+                    {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+            });
+        }
+        public void RecipeStepSkip(string module, string recipeName, string recipeStep)
+        {
+            EV.Notify(UniversalEvents.RecipeStepSkip, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+            {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+            });
+        }
+
+        public void RecipeStop(string module, string recipeName, string recipeStep)
+        {
+            EV.Notify(UniversalEvents.RecipeStop, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+            {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+            });
+        }
+
+        public void RecipeJumpStep(string module, string recipeName, string recipeStep, string jumpStpeId)
+        {
+            EV.Notify(UniversalEvents.RecipeJumpStep, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+             {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+                {DataName.StepId.ToString(),  jumpStpeId},
+            });
+        }
+        public void RecipeAbort(string module, string recipeName, string recipeStep)
+        {
+            EV.Notify(UniversalEvents.RecipeAbort, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+                   {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+            });
+        }
+
+        public void RecipeJumpEnd(string module, string recipeName, string recipeStep, string jumpStpeId)
+        {
+            EV.Notify(UniversalEvents.RecipeJumpEnd, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+             {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+                {DataName.StepId.ToString(),  jumpStpeId},
+            });
+        }
+
+        public void RecipeCallAlarmRecipe(string module, string recipeName, string recipeStep, string otherRecipeName)
+        {
+            EV.Notify(UniversalEvents.CallAlarmRecipe, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+              {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+                {DataName.CallRecipeID.ToString(),  otherRecipeName},
+            });
+        }
+        public void RecipeCallAbortRecipe(string module, string recipeName, string recipeStep, string otherRecipeName)
+        {
+            EV.Notify(UniversalEvents.CallAbortRecipe, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+             {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+                 {DataName.CallRecipeID.ToString(),  otherRecipeName},
+            });
+        }
+        public void RecipeRunResetRecipe(string module, string recipeName, string recipeStep, string otherRecipeName)
+        {
+            EV.Notify(UniversalEvents.RunResetRecipe, new SerializableDictionary<string, string>()
+            {
+                {DVIDName.RecipeID,  recipeName},
+                {DataName.NewRecipeStepNumber.ToString(),  recipeStep},
+             {DataName.CallRecipeID.ToString(),  otherRecipeName},
+            });
+        }
     }
 }
 

+ 48 - 0
Furnace/FurnaceRT/Equipments/Schedulers/SchedulerFACallback.cs

@@ -98,6 +98,19 @@ namespace FurnaceRT.Equipments.Schedulers
                 EV.Subscribe(new EventItem("Event", UniversalEvents.SideDummyStateWarning, $"SideDummyStateWarning"));
                 EV.Subscribe(new EventItem("Event", UniversalEvents.ExtraDummyStateWarning, $"ExtraDummyStateWarning"));
 
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeStop, $"RecipeStop"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeHold, $"RecipeHold"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeRelease, $"RecipeRelease"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeJumpStep, $"RecipeJumpStep"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeJumpEnd, $"RecipeJumpEnd"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeAbort, $"RecipeAbort"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.CallAlarmRecipe, $"CallAlarmRecipe"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.CallAbortRecipe, $"CallAbortRecipe"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RunResetRecipe, $"RunResetRecipe"));
+                EV.Subscribe(new EventItem("Event", UniversalEvents.RecipeStepSkip, $"RecipeStepSkip"));
+
+
+
                 PortId[module] = i.ToString();
                 PortJobStarted[module] = $"{module}JobStarted";
                 PortJobStopped[module] = $"{module}JobStopped";
@@ -572,5 +585,40 @@ namespace FurnaceRT.Equipments.Schedulers
             bufinfo.Add("BUFPara", unallocatedPartitionCapacity, SECsFormat.U1);
             return bufinfo;
         }
+
+
+        public void CJPaused(ControlJobInfo cj, ProcessJobInfo pj)
+        {
+            if (cj != null)
+            {
+                EV.Notify(Gem300Events.CJ_PAUSED, new SerializableDictionary<string, object>()
+                {
+                    {DataVariables.CJID,  cj.Name},
+                    {DataVariables.PRJobID,  cj.Name},
+                });
+            }
+        }
+        public void CJResume(ControlJobInfo cj, ProcessJobInfo pj)
+        {
+            if (cj != null)
+            {
+                EV.Notify(Gem300Events.CJ_RESUME, new SerializableDictionary<string, object>()
+                {
+                    {DataVariables.CJID,  cj.Name},
+                       {DataVariables.PRJobID,  pj.Name},
+                });
+            }
+        }
+        public void CJAbort(ControlJobInfo cj, ProcessJobInfo pj)
+        {
+            if (cj != null)
+            {
+                EV.Notify(Gem300Events.CJ_ABORTED, new SerializableDictionary<string, object>()
+                {
+                    {DataVariables.CJID,  cj.Name},
+                    {DataVariables.PRJobID,  pj.Name},
+                });
+            }
+        }
     }
 }

+ 0 - 7
Furnace/FurnaceUI/Views/Operations/StatusViewModel.cs

@@ -970,13 +970,6 @@ namespace FurnaceUI.Views.Operations
         {
             get { return (CycleSetPoint > 0 && (CycledCount > CycleSetPoint)) ? $"{CycledCount + 1}/{CycleSetPoint}" : $"{CycledCount}/{CycleSetPoint}"; }
         }
-        [Subscription("SubRecipeStepName")]        public string SubRecipeStepName { get; set; }
-        [Subscription("SubRecipeStepNumber")]        public string SubRecipeStepNumber { get; set; }
-        [Subscription("ProcessRecipeStepName")]        public string ProcessRecipeStepName { get; set; }
-        [Subscription("PM1.RecipeStepNumber")]        public int RecipeStepNumber { get; set; }
-        [Subscription("ProcessRecipeStepNumber")]        public string ProcessRecipeStepNumber { get; set; }
-        [Subscription("IsInSubProcessing")]        public bool IsInSubProcessing { get; set; }
-
 
         [Subscription("Scheduler.ControlJobList")]
         public List<ControlJobInfo> LocalControlJobs