添加 MX-PD-盘古 项目文件

将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
Shi.Ji
2026-05-18 11:43:09 +08:00
parent 03632a379d
commit e31d3560bb
739 changed files with 99783 additions and 0 deletions

View File

@@ -0,0 +1,203 @@
using MainShell.Common;
using MainShell.ProcessResult;
using MW.WorkFlow;
using System;
using System.Threading.Tasks;
namespace MainShell.Process
{
public abstract class ActivityAbstractBase : IActivity
{
public string Name { get; protected set; }
protected ProcessResultManager ResultManager { get; private set; }
protected string CurrentWorkflowName { get; private set; } = "UnknownFlow";
protected string ParentActivityName { get; private set; } = string.Empty;
protected ActivityAbstractBase(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Activity name cannot be null or whitespace.", nameof(name));
}
Name = name;
}
public async Task<ActivityResult> ExecuteAsync(WorkflowContext context, ActivityControl activityControl)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (activityControl == null)
{
throw new ArgumentNullException(nameof(activityControl));
}
var result = ActivityResult.Failure;
var hasFaulted = false;
try
{
if (context.TryGetData<string>(WorkflowContextKeys.WorkflowName, out var flowName))
{
CurrentWorkflowName = flowName;
}
if (context.TryGetData<string>(WorkflowContextKeys.ParentActivityName, out var parentName))
{
ParentActivityName = parentName;
}
else
{
ParentActivityName = string.Empty;
}
if (context.TryGetData<ProcessResultManager>(WorkflowContextKeys.ProcessResultManager, out var manager))
{
ResultManager = manager;
ResultManager.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Running, null);
}
PrepareExecute(context, activityControl);
result = await OnExecuteAsync(context, activityControl);
return result;
}
catch (OperationCanceledException)
{
ResultManager?.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Canceled, null);
throw;
}
catch (Exception ex)
{
if (!HasWorkflowFailure(context))
{
SetWorkflowFailure(
context,
MessageKey.ProcessStepFailedWithReason,
new object[] { Name, ex.Message ?? string.Empty });
}
var errorMsg = ResolveWorkflowFailureMessage(context);
ResultManager?.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Faulted, errorMsg);
hasFaulted = true;
throw;
}
finally
{
AfterExecute(context, activityControl);
if (ResultManager != null && !hasFaulted)
{
if (result == ActivityResult.Success)
{
ResultManager.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Completed, null);
}
else if (result == ActivityResult.Canceled)
{
ResultManager.UpdateFlowState(CurrentWorkflowName, ParentActivityName, Name, ProcessExecutionStatus.Canceled, null);
}
else
{
ResultManager.UpdateFlowState(
CurrentWorkflowName,
ParentActivityName,
Name,
ProcessExecutionStatus.Faulted,
ResolveWorkflowFailureMessage(context));
}
}
}
}
protected ActivityResult Fail(WorkflowContext context, MessageKey failureMessageKey, object[] failureMessageArguments)
{
SetWorkflowFailure(context, failureMessageKey, failureMessageArguments);
return ActivityResult.Failure;
}
protected void SetWorkflowFailure(WorkflowContext context, MessageKey failureMessageKey, object[] failureMessageArguments)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var normalized = NormalizeFailureMessageArguments(failureMessageArguments);
context.SetData(WorkflowContextKeys.WorkflowFailureMessageKey, failureMessageKey);
context.SetData(WorkflowContextKeys.WorkflowFailureMessageArguments, normalized);
context.SetData(WorkflowContextKeys.WorkflowFailureMessage, LanguageResourceHelper.Format(failureMessageKey, normalized));
}
protected void SetWorkflowFailure(WorkflowContext context, string failureMessage)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
context.SetData(WorkflowContextKeys.WorkflowFailureMessageKey, MessageKey.None);
context.SetData<object[]>(WorkflowContextKeys.WorkflowFailureMessageArguments, null);
context.SetData(WorkflowContextKeys.WorkflowFailureMessage, failureMessage ?? string.Empty);
}
protected bool HasWorkflowFailure(WorkflowContext context)
{
if (context.TryGetData<MessageKey>(WorkflowContextKeys.WorkflowFailureMessageKey, out var failureMessageKey) &&
failureMessageKey > MessageKey.None)
{
return true;
}
return context.TryGetData<string>(WorkflowContextKeys.WorkflowFailureMessage, out var failureMessage) &&
!string.IsNullOrWhiteSpace(failureMessage);
}
protected string ResolveWorkflowFailureMessage(WorkflowContext context)
{
if (context.TryGetData<MessageKey>(WorkflowContextKeys.WorkflowFailureMessageKey, out var failureMessageKey) &&
failureMessageKey > MessageKey.None)
{
return LanguageResourceHelper.Format(failureMessageKey, GetWorkflowFailureMessageArguments(context));
}
if (context.TryGetData<string>(WorkflowContextKeys.WorkflowFailureMessage, out var failureMessage) &&
!string.IsNullOrWhiteSpace(failureMessage))
{
return failureMessage;
}
return string.Empty;
}
protected object[] GetWorkflowFailureMessageArguments(WorkflowContext context)
{
if (context.TryGetData<object[]>(WorkflowContextKeys.WorkflowFailureMessageArguments, out var failureMessageArguments) &&
failureMessageArguments != null)
{
return failureMessageArguments;
}
return Array.Empty<object>();
}
protected object[] NormalizeFailureMessageArguments(object[] failureMessageArguments)
{
return failureMessageArguments ?? Array.Empty<object>();
}
protected abstract Task<ActivityResult> OnExecuteAsync(WorkflowContext context, ActivityControl activityControl);
protected virtual void PrepareExecute(WorkflowContext context, ActivityControl activityControl)
{
}
protected virtual void AfterExecute(WorkflowContext context, ActivityControl activityControl)
{
}
}
}

View File

@@ -0,0 +1,110 @@
using MainShell.Common;
using MW.WorkFlow;
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
namespace MainShell.Process
{
public class CompositeActivity : IActivity
{
private readonly IEnumerable<IActivity> _subSteps;
private readonly IEnumerable<IActivity> _finallySteps;
public string Name { get; }
public CompositeActivity(string name, IEnumerable<IActivity> subSteps)
: this(name, subSteps, Array.Empty<IActivity>())
{
}
public CompositeActivity(string name, IEnumerable<IActivity> subSteps, IEnumerable<IActivity> finallySteps)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Composite activity name cannot be null or whitespace.", nameof(name));
}
Name = name;
_subSteps = subSteps ?? throw new ArgumentNullException(nameof(subSteps));
_finallySteps = finallySteps ?? Array.Empty<IActivity>();
}
public async Task<ActivityResult> ExecuteAsync(WorkflowContext context, ActivityControl activityControl)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (activityControl == null)
{
throw new ArgumentNullException(nameof(activityControl));
}
activityControl.ThrowIfCancellationRequested();
context.TryGetData<string>(WorkflowContextKeys.ParentActivityName, out var previousParent);
context.SetData(WorkflowContextKeys.ParentActivityName, Name);
ActivityResult result = ActivityResult.Success;
Exception mainException = null;
Exception cleanupException = null;
try
{
foreach (IActivity step in _subSteps)
{
activityControl.ThrowIfCancellationRequested();
result = await step.ExecuteAsync(context, activityControl);
if (result != ActivityResult.Success)
{
break;
}
}
}
catch (Exception ex)
{
mainException = ex;
}
finally
{
foreach (IActivity cleanupStep in _finallySteps)
{
try
{
ActivityResult cleanupResult = await cleanupStep.ExecuteAsync(context, activityControl);
if (mainException == null && result == ActivityResult.Success && cleanupResult != ActivityResult.Success)
{
result = cleanupResult;
}
}
catch (Exception ex)
{
if (mainException == null && result == ActivityResult.Success)
{
cleanupException = ex;
break;
}
}
}
context.SetData(WorkflowContextKeys.ParentActivityName, previousParent ?? string.Empty);
}
if (mainException != null)
{
ExceptionDispatchInfo.Capture(mainException).Throw();
}
if (cleanupException != null)
{
ExceptionDispatchInfo.Capture(cleanupException).Throw();
}
return result;
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MainShell.Process
{
public class ProcessFlowName
{
public const string AutoProduction = "AutoProduction";
/// <summary>
/// 基板上料
/// </summary>
public const string SubstrateLoadFlow = "SubstrateLoadFlow";
/// <summary>
/// 基板定位
/// </summary>
public const string SubstratePositionFlow = "SubstratePositionFlow";
/// <summary>
/// 芯片拉直
/// </summary>
public const string ChipStraighteningFlow = "WaferAngleAdjustmentFlow";
/// <summary>
/// 芯片定位
/// </summary>
public const string DiePositionFlow = "DiePositionFlow";
/// <summary>
/// 芯片转移
/// </summary>
public const string DieTransferFlow = "DieTransferFlow";
/// <summary>
/// 基板测高
/// </summary>
public const string SubstrateHeightMeasureFlow = "SubstrateHeightMeasureFlow";
/// <summary>
/// 精度复检
/// </summary>
public const string DieRecheckFlow = "DieRecheckFlow";
/// <summary>
/// 基板下料
/// </summary>
public const string SubstrateUnloadFlow = "SubstrateUnloadFlow";
public const string PreparationSignalFlow = "PreparationSignalFlow";
public const string ChipPreparationAutoLoadStartFlow = "ChipPreparationAutoLoadStartFlow";
public const string ChipPreparationSyncFlow = "ChipPreparationSyncFlow";
public const string PreTransferValidationFlow = "PreTransferValidationFlow";
public const string ChipUnloadFlow = "ChipUnloadFlow";
public const string ChipPreparationOnDemandFlow = "ChipPreparationOnDemand";
public const string ChipLoadExecuteActivity = "ChipLoadExecute";
public const string ChipUnloadExecuteActivity = "ChipUnloadExecute";
}
public enum DieTransferRoute
{
None = 0,
Recheck = 1
}
public enum AutoProductionRoute
{
None = 0,
ContinueCurrentSubstrate = 1,
Recheck = 2,
ChipExhausted = 3,
SubstrateComplete = 4,
BothExhausted = 5
}
}

View File

@@ -0,0 +1,273 @@
using MainShell.Common;
using MainShell.ProcessResult;
using MW.WorkFlow;
using Stylet;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace MainShell.Process
{
public class WorkflowRunCompletedEventArgs : EventArgs
{
public WorkflowState FinalState { get; }
public string Error { get; }
public string FailureMessage { get; }
public MessageKey FailureMessageKey { get; }
public object[] FailureMessageArguments { get; }
public WorkflowRunCompletedEventArgs(WorkflowState finalState, string error, string failureMessage, MessageKey failureMessageKey, object[] failureMessageArguments)
{
FinalState = finalState;
Error = error;
FailureMessage = failureMessage;
FailureMessageKey = failureMessageKey;
FailureMessageArguments = failureMessageArguments ?? Array.Empty<object>();
}
}
/// <summary>
/// 封装工作流的启动、停止和状态管理,用于手动流程的复用。
/// </summary>
public class
WorkflowRunner : PropertyChangedBase, IDisposable
{
private WorkflowEngine _workflowEngine;
private bool _isRunning;
/// <summary>
/// 流程是否正在运行
/// </summary>
public bool IsRunning
{
get { return _isRunning; }
private set { SetAndNotify(ref _isRunning, value); }
}
public event EventHandler<WorkflowRunCompletedEventArgs> RunCompleted;
/// <summary>
/// 运行单个 Activity自动包装为单步工作流
/// </summary>
public Task RunActivityAsync(IActivity activity, WorkflowContext context)
{
if (activity == null) throw new ArgumentNullException(nameof(activity));
// 自动构建单步工作流定义
var stepId = "SingleStep_" + Guid.NewGuid().ToString("N");
var step = new WorkflowStep(stepId, activity);
var definition = new WorkflowDefinition(stepId);
definition.AddStep(step);
return RunAsync(definition, context);
}
public Task<WorkflowRunCompletedEventArgs> RunActivityWithResultAsync(IActivity activity, WorkflowContext context)
{
if (activity == null) throw new ArgumentNullException(nameof(activity));
var stepId = "SingleStep_" + Guid.NewGuid().ToString("N");
var step = new WorkflowStep(stepId, activity);
var definition = new WorkflowDefinition(stepId);
definition.AddStep(step);
return RunWithResultAsync(definition, context, null);
}
/// <summary>
/// 运行完整的工作流定义
/// </summary>
public async Task RunAsync(WorkflowDefinition definition, WorkflowContext context)
{
await RunWithResultAsync(definition, context, null);
}
public Task<WorkflowRunCompletedEventArgs> RunWithResultAsync(WorkflowDefinition definition, WorkflowContext context)
{
return RunWithResultAsync(definition, context, null);
}
/// <summary>
/// 运行完整的工作流定义,并支持从指定步骤启动。
/// </summary>
/// <param name="definition">工作流定义</param>
/// <param name="context">工作流上下文</param>
/// <param name="startStepId">可选指定起始步骤ID为 null/空时从初始步骤启动</param>
public async Task RunAsync(WorkflowDefinition definition, WorkflowContext context, string startStepId)
{
await RunWithResultAsync(definition, context, startStepId);
}
public async Task<WorkflowRunCompletedEventArgs> RunWithResultAsync(WorkflowDefinition definition, WorkflowContext context, string startStepId)
{
if (definition == null) throw new ArgumentNullException(nameof(definition));
if (context == null) throw new ArgumentNullException(nameof(context));
if (IsRunning)
{
throw new InvalidOperationException("当前已有流程正在运行,无法重复启动。");
}
if (!string.IsNullOrWhiteSpace(startStepId) && !definition.GetAllStepIds().Contains(startStepId))
{
throw new ArgumentException($"指定的起始步骤ID '{startStepId}' 不存在于工作流定义中。", nameof(startStepId));
}
var resolvedStartStepId = ResolveStartStepId(definition, context, startStepId);
var errorStr = string.Empty;
WorkflowState finalState = WorkflowState.Created;
MessageKey failureMessageKey = MessageKey.None;
object[] failureMessageArguments = Array.Empty<object>();
string failureMessage = string.Empty;
try
{
IsRunning = true;
_workflowEngine = new WorkflowEngine(definition, context);
_workflowEngine.Start(resolvedStartStepId);
// 异步轮询等待工作流结束
// 这样可以不阻塞 UI 线程,同时保持 IsRunning 状态正确
while (_workflowEngine != null && _workflowEngine.IsWorkflowRunning)
{
await Task.Delay(100);
}
// 捕获最终状态Dispose 之前)
if (_workflowEngine != null)
{
finalState = _workflowEngine.CurrentState;
}
failureMessageKey = ResolveFailureMessageKey(context);
failureMessageArguments = ResolveFailureMessageArguments(context);
failureMessage = ResolveFailureMessage(context, failureMessageKey, failureMessageArguments);
}
finally
{
// 无论正常结束、异常还是被取消,都确保清理资源和复位状态
errorStr = _workflowEngine?.LastException?.ToString();
IsRunning = false;
_workflowEngine?.Dispose();
_workflowEngine = null;
}
var completedArgs = new WorkflowRunCompletedEventArgs(finalState, errorStr, failureMessage, failureMessageKey, failureMessageArguments);
RunCompleted?.Invoke(this, completedArgs);
return completedArgs;
}
/// <summary>
/// 从指定步骤启动工作流(语义化封装)。
/// </summary>
public Task RunFromStepAsync(WorkflowDefinition definition, WorkflowContext context, string startStepId)
{
if (string.IsNullOrWhiteSpace(startStepId))
throw new ArgumentNullException(nameof(startStepId));
return RunAsync(definition, context, startStepId);
}
public Task<WorkflowRunCompletedEventArgs> RunFromStepWithResultAsync(WorkflowDefinition definition, WorkflowContext context, string startStepId)
{
if (string.IsNullOrWhiteSpace(startStepId))
throw new ArgumentNullException(nameof(startStepId));
return RunWithResultAsync(definition, context, startStepId);
}
private string ResolveStartStepId(WorkflowDefinition definition, WorkflowContext context, string startStepId)
{
if (!string.IsNullOrWhiteSpace(startStepId))
{
return startStepId;
}
if (!context.TryGetData<string>(WorkflowContextKeys.WorkflowName, out var workflowName) ||
string.IsNullOrWhiteSpace(workflowName) ||
!context.TryGetData<ProcessResultManager>(WorkflowContextKeys.ProcessResultManager, out var resultManager) ||
resultManager == null ||
!resultManager.TryGetResumeStepId(workflowName, out var resumeStepId) ||
!definition.ContainsStep(resumeStepId))
{
return null;
}
return resumeStepId;
}
private MessageKey ResolveFailureMessageKey(WorkflowContext context)
{
MessageKey failureMessageKey;
if (context.TryGetData<MessageKey>(WorkflowContextKeys.WorkflowFailureMessageKey, out failureMessageKey))
{
return failureMessageKey;
}
return MessageKey.None;
}
private object[] ResolveFailureMessageArguments(WorkflowContext context)
{
object[] failureMessageArguments;
if (context.TryGetData<object[]>(WorkflowContextKeys.WorkflowFailureMessageArguments, out failureMessageArguments) &&
failureMessageArguments != null)
{
return failureMessageArguments;
}
return Array.Empty<object>();
}
private string ResolveFailureMessage(WorkflowContext context, MessageKey failureMessageKey, object[] failureMessageArguments)
{
if (failureMessageKey != MessageKey.None)
{
return LanguageResourceHelper.Format(failureMessageKey, failureMessageArguments);
}
string failureMessage;
if (context.TryGetData<string>(WorkflowContextKeys.WorkflowFailureMessage, out failureMessage) &&
!string.IsNullOrWhiteSpace(failureMessage))
{
return failureMessage;
}
return string.Empty;
}
/// <summary>
/// 请求停止当前流程
/// </summary>
public async Task StopAsync()
{
if (_workflowEngine != null && _workflowEngine.IsWorkflowRunning)
{
await _workflowEngine.StopAsync();
}
}
public void Pause()
{
if (_workflowEngine != null && _workflowEngine.IsWorkflowRunning)
{
_workflowEngine.Pause();
}
}
public void Resume()
{
if (_workflowEngine != null && _workflowEngine.IsWorkflowRunning)
{
_workflowEngine.Resume();
}
}
public void Dispose()
{
_workflowEngine?.Dispose();
}
}
}

View File

@@ -0,0 +1,56 @@
using MainShell.Log;
using MainShell.ProcessResult;
using System;
using MW.WorkFlow;
namespace MainShell.Process
{
public class WorkflowRuntimeTracker : IWorkflowRuntimeTracker
{
private readonly ProcessResultManager _processResultManager;
public WorkflowRuntimeTracker(ProcessResultManager processResultManager)
{
_processResultManager = processResultManager ?? throw new ArgumentNullException(nameof(processResultManager));
}
public void UpdateExecutionPointer(WorkflowExecutionPointer executionPointer)
{
if (executionPointer != null)
{
string.Format(
"Workflow pointer updated. WorkflowName={0}, FlowName={1}, ActivityName={2}, CurrentStepId={3}, NextStepId={4}, UpdatedAt={5:yyyy-MM-dd HH:mm:ss.fff}.",
NormalizeValue(executionPointer.WorkflowName),
NormalizeValue(executionPointer.FlowName),
NormalizeValue(executionPointer.ActivityName),
NormalizeValue(executionPointer.CurrentStepId),
NormalizeValue(executionPointer.NextStepId),
executionPointer.UpdatedAt).LogProcessDebug();
}
_processResultManager.UpdateExecutionPointer(executionPointer);
}
public void ReportWorkflowFault(WorkflowFaultInfo faultInfo)
{
if (faultInfo != null)
{
string.Format(
"Workflow fault reported. WorkflowName={0}, FlowName={1}, ActivityName={2}, CurrentStepId={3}, OccurredAt={4:yyyy-MM-dd HH:mm:ss.fff}, ErrorMessage={5}.",
NormalizeValue(faultInfo.WorkflowName),
NormalizeValue(faultInfo.FlowName),
NormalizeValue(faultInfo.ActivityName),
NormalizeValue(faultInfo.CurrentStepId),
faultInfo.OccurredAt,
NormalizeValue(faultInfo.ErrorMessage)).LogProcessError();
}
_processResultManager.ReportWorkflowFault(faultInfo);
}
private static string NormalizeValue(string value)
{
return string.IsNullOrWhiteSpace(value) ? "N/A" : value;
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using MW.WorkFlow;
namespace MainShell.Process
{
public class WorkflowStartRequest
{
public WorkflowDefinition Definition { get; }
public WorkflowContext Context { get; }
public string StartStepId { get; }
public WorkflowStartRequest(WorkflowDefinition definition, WorkflowContext context, string startStepId)
{
Definition = definition ?? throw new ArgumentNullException(nameof(definition));
Context = context ?? throw new ArgumentNullException(nameof(context));
StartStepId = startStepId;
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
namespace MainShell.Process
{
public static class WorkflowStepIdResolver
{
private static readonly IReadOnlyDictionary<string, string> AutoProductionEntryStepIdMap =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ ProcessFlowName.SubstrateLoadFlow, WorkflowStepIds.AutoProduction.SubstrateLoadEntry },
{ ProcessFlowName.SubstratePositionFlow, WorkflowStepIds.AutoProduction.SubstratePositionEntry },
{ ProcessFlowName.SubstrateHeightMeasureFlow, WorkflowStepIds.AutoProduction.SubstrateHeightMeasureEntry },
{ ProcessFlowName.PreparationSignalFlow, WorkflowStepIds.AutoProduction.PreparationSignalEntry },
{ ProcessFlowName.ChipPreparationSyncFlow, WorkflowStepIds.AutoProduction.ChipPreparationSyncEntry },
{ ProcessFlowName.PreTransferValidationFlow, WorkflowStepIds.AutoProduction.PreTransferValidationEntry },
{ ProcessFlowName.ChipStraighteningFlow, WorkflowStepIds.AutoProduction.ChipStraighteningEntry },
{ ProcessFlowName.DiePositionFlow, WorkflowStepIds.AutoProduction.DiePositionEntry },
{ ProcessFlowName.DieTransferFlow, WorkflowStepIds.AutoProduction.DieTransferEntry },
{ ProcessFlowName.DieRecheckFlow, WorkflowStepIds.AutoProduction.DieRecheckEntry },
{ ProcessFlowName.ChipUnloadFlow, WorkflowStepIds.AutoProduction.ChipUnloadEntry },
{ ProcessFlowName.SubstrateUnloadFlow, WorkflowStepIds.AutoProduction.SubstrateUnloadEntry }
};
public static string GetAutoProductionEntryStepId(string flowName)
{
if (TryGetAutoProductionEntryStepId(flowName, out var stepId))
{
return stepId;
}
return WorkflowStepIds.AutoProduction.SubstrateLoadEntry;
}
public static bool TryGetAutoProductionEntryStepId(string flowName, out string stepId)
{
if (string.IsNullOrWhiteSpace(flowName))
{
stepId = null;
return false;
}
return AutoProductionEntryStepIdMap.TryGetValue(flowName, out stepId);
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace MainShell.Process
{
public static class WorkflowStepIds
{
public static class AutoProduction
{
public const string SubstrateLoadEntry = "Auto.SubstrateLoad.Entry";
public const string SubstratePositionEntry = "Auto.SubstratePosition.Entry";
public const string SubstrateHeightMeasureEntry = "Auto.SubstrateHeightMeasure.Entry";
public const string PreparationSignalEntry = "Auto.PreparationSignal.Entry";
public const string ChipPreparationSyncEntry = "Auto.ChipPreparationSync.Entry";
public const string PreTransferValidationEntry = "Auto.PreTransferValidation.Entry";
public const string ChipStraighteningEntry = "Auto.ChipStraightening.Entry";
public const string DiePositionEntry = "Auto.DiePosition.Entry";
public const string DieTransferEntry = "Auto.DieTransfer.Entry";
public const string DieRecheckEntry = "Auto.DieRecheck.Entry";
public const string ChipUnloadEntry = "Auto.ChipUnload.Entry";
public const string SubstrateUnloadEntry = "Auto.SubstrateUnload.Entry";
}
}
}