ProductionUiCordonel: - re-organized to support multiple production processes part 7
This commit is contained in:
+56
-49
@@ -94,11 +94,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
private Timer _processCtrlTimer;
|
||||
private const Int32 ProcessTimerCycleMs = 250;
|
||||
|
||||
// defines for state machine
|
||||
/// <summary>
|
||||
/// Avoid waiting for a single process completion.
|
||||
/// </summary>
|
||||
private const IProductionProcess DoNotWaitForSingleProcessCompletion = null;
|
||||
public const IProductionProcess DoNotWaitForSingleProcessCompletion = null;
|
||||
|
||||
/// <summary>
|
||||
/// Kick off a parallel execution of the state machine.
|
||||
/// </summary>
|
||||
public const Boolean ExecuteInParallel = true;
|
||||
|
||||
#endregion --------------------------------------- Variables --------------------------------------------------
|
||||
#region ------------------------------------------ Class ------------------------------------------------------
|
||||
@@ -289,7 +293,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
#region ------------------------------------------ State Machine ----------------------------------------------
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract void IndividualStateMachine(IProductionProcess process);
|
||||
public abstract void IndividualStateMachine(ProcessStateStruct processSatProcessStateStruct);
|
||||
|
||||
/// <summary>
|
||||
/// State machine of ProcessController which serves as template for all production processes.
|
||||
@@ -298,7 +302,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// INSTRUCTION FOR NORMAL USAGE:
|
||||
/// -----------------------------
|
||||
/// Call the SetupProcess() with the
|
||||
/// - new process automatically collected from <see cref="ProcessStates.GetProcessOfState"/> with new
|
||||
/// - new process automatically collected from <see cref="BaseProcessStates.GetProcessOfState"/> with new
|
||||
/// _actualProcessState as input,
|
||||
/// - successExitState set to the next required state after successfully execution.
|
||||
/// That's it! The normal state change has always only one production process active and waits for completion
|
||||
@@ -314,7 +318,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// other. One example is a database access for data collection from different tables.
|
||||
///
|
||||
/// Call the SetupProcess with the
|
||||
/// - new process automatically collected from <see cref="ProcessStates.GetProcessOfState"/> with new
|
||||
/// - new process automatically collected from <see cref="BaseProcessStates.GetProcessOfState"/> with new
|
||||
/// _actualProcessState as input,
|
||||
/// - successExitState being set to <see cref="BaseProductionProcess.DoNotChangeStateAfterCompletion"/> (null).
|
||||
/// This will lock the sate change after completion as multiple processes may be active and a state change after
|
||||
@@ -342,6 +346,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2023-Jan-17" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Generic implementation
|
||||
/// </remarks>
|
||||
private void GenericStateMachine()
|
||||
{// avoid repeated execution of the state machine on unchanged state
|
||||
if (_stateMachineState == _lockedProcessState)
|
||||
@@ -361,8 +368,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
// signal state change to logger
|
||||
OnOverallProcessStateChanged?.Invoke(this, new ProcessStateArgs(_stateMachineState));
|
||||
|
||||
// get the processStateStruct of the actual set stateMachineSTate
|
||||
var processStateStruct = _processStateDef.GetProcessStateStructOfState(_stateMachineState);
|
||||
|
||||
// get the actual required process from the state definition list
|
||||
var process = _processStateDef?.GetProcessOfState(_stateMachineState);
|
||||
//var process = _processStateDef?.GetProcessOfState(_stateMachineState);
|
||||
|
||||
switch (_stateMachineState)
|
||||
{
|
||||
@@ -386,7 +396,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
|
||||
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
|
||||
// to change the state after successfully execution. The detection is the base for all others.
|
||||
StartProcess(process, ProcessState.CheckNewMeter);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.CheckNewMeter:
|
||||
@@ -400,7 +410,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
case ProcessState.ConnectCordonel:
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
StartProcess(process, BaseProductionProcess.DoNotChangeStateAfterCompletion);
|
||||
StartProcess(processStateStruct);
|
||||
// Do not wait on completion as new parallel process can be started by manually state change.
|
||||
_stateMachineState = ProcessState.GetSerialNumberAndRadioAddress;
|
||||
break;
|
||||
@@ -408,19 +418,19 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
case ProcessState.GetSerialNumberAndRadioAddress:
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
StartProcess(process, BaseProductionProcess.DoNotChangeStateAfterCompletion);
|
||||
StartProcess(processStateStruct);
|
||||
// Do not wait on completion as new parallel process can be started by manually state change.
|
||||
_stateMachineState = ProcessState.GetProgrammingParameters;
|
||||
break;
|
||||
|
||||
case ProcessState.CheckOrderNumber:
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
StartProcess(process, ProcessState.CheckSerialNumber, waitForAllProcesses: true);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.CheckSerialNumber:
|
||||
// This scans the serial number, it has to be executed exclusively with automatic
|
||||
StartProcess(process, ProcessState.CheckAttachments);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.RepeatFailedTests:
|
||||
@@ -451,7 +461,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
// Start the error handler with its user feedback request. It has to be started
|
||||
// always even if the abortion of all processes is required! The error handler
|
||||
// will change the exit state based on the user input.
|
||||
StartProcess(process, ProcessState.Idle, startAlways: true);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.StateListDelimiter:
|
||||
@@ -459,7 +469,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
break;
|
||||
|
||||
default:
|
||||
IndividualStateMachine(process);
|
||||
// This is the call to the processes for a specific test e.g. EOL or Picking
|
||||
IndividualStateMachine(processStateStruct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -664,7 +675,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
if (Processes == null)
|
||||
Processes = new List<IProductionProcess>();
|
||||
if (_processStateDef == null)
|
||||
_processStateDef = new EolProcessStates();
|
||||
_processStateDef = new EolStateMachineCtrl();
|
||||
|
||||
// get all processes relevant for EOL from table which has to be sorted
|
||||
var processes = _processStateDef.GetAllEolRelevantProcesses();
|
||||
@@ -693,14 +704,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// - Adds event handlers for process information,
|
||||
/// - Starts process.
|
||||
/// </summary>
|
||||
/// <param name="process"></param>
|
||||
/// <param name="successExitState"></param>
|
||||
/// <param name="errorExitState"></param>
|
||||
/// <param name="breakExitState"></param>
|
||||
/// <param name="waitForSingleProcess">wait for single processes to complete before execution</param>
|
||||
/// <param name="waitForAllProcesses">wait for all processes to complete before execution</param>
|
||||
/// <param name="startAlways">start even if abort is required</param>
|
||||
/// <returns>actual state</returns>
|
||||
/// <param name="processStateStruct"></param>
|
||||
/// <returns>actual state</returns>
|
||||
/// <remarks date="2023-Jan-31" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
@@ -719,41 +724,42 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
|
||||
/// - Changed setup process to start process being able to create a process list in advance.
|
||||
/// </remarks>
|
||||
protected void StartProcess(IProductionProcess process, ProcessState? successExitState,
|
||||
ProcessState errorExitState = ProcessState.Error, ProcessState breakExitState = ProcessState.Stop,
|
||||
IProductionProcess waitForSingleProcess = DoNotWaitForSingleProcessCompletion,
|
||||
Boolean waitForAllProcesses = false, Boolean startAlways = false)
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Feed with processStateStruct.
|
||||
/// </remarks>
|
||||
protected void StartProcess(ProcessStateStruct processStateStruct)
|
||||
{
|
||||
// deny access if uninitialized
|
||||
if (Processes == null || process == null)
|
||||
if (Processes == null || processStateStruct.ProductionProcess == null)
|
||||
return;
|
||||
|
||||
// do not start a new process if any error or abort request is signaled
|
||||
if (!startAlways && AnyProcessRequiresAbortion())
|
||||
if (AnyProcessRequiresAbortion() && !processStateStruct.StartAlways )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// process is waiting for execution after init, this overrides the eventually abort state
|
||||
process.InitProcess();
|
||||
processStateStruct.ProductionProcess.InitProcess();
|
||||
|
||||
// wait for a single process to complete before start of new depending on process
|
||||
if (waitForSingleProcess != DoNotWaitForSingleProcessCompletion)
|
||||
if (processStateStruct.WaitForSingleProcess != null)
|
||||
{
|
||||
// each process will have its own timer until a timeout will change the state
|
||||
while (Processes.Any(pp => pp.ProcessName == waitForSingleProcess.ProcessName
|
||||
&& WaitForProcess(pp)
|
||||
&& !AnyProcessRequiresAbortion()))
|
||||
while (Processes.Any(pp => !AnyProcessRequiresAbortion()
|
||||
&& _processStateDef.GetStateOfProcess(pp) == processStateStruct.WaitForSingleProcess
|
||||
&& WaitForProcess(pp)))
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
// wait for all initialized processes to complete before start the new process
|
||||
if (waitForAllProcesses)
|
||||
if (processStateStruct.WaitForAllProcesses)
|
||||
{
|
||||
// each process will have its own timer until a timeout will change the state,
|
||||
// avoid checking the new process, which is not started due to this waiting loop
|
||||
while (Processes.Any(pp => pp.ProcessName != process.ProcessName
|
||||
while (Processes.Any(pp => pp.ProcessName != processStateStruct.ProductionProcess.ProcessName
|
||||
&& WaitForProcess(pp)
|
||||
&& !AnyProcessRequiresAbortion()))
|
||||
{
|
||||
@@ -762,28 +768,29 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
}
|
||||
|
||||
// if any process exits meanwhile with an error or abort request avoid a start of this process
|
||||
if ((!startAlways && AnyProcessRequiresAbortion())
|
||||
|| process.SingleProcessState == SingleProcessState.Idle
|
||||
|| process.SingleProcessState == SingleProcessState.Abort)
|
||||
if (( !processStateStruct.StartAlways && AnyProcessRequiresAbortion())
|
||||
|| processStateStruct.ProductionProcess.SingleProcessState == SingleProcessState.Idle
|
||||
|| processStateStruct.ProductionProcess.SingleProcessState == SingleProcessState.Abort)
|
||||
{
|
||||
process.AbortProcess();
|
||||
processStateStruct.ProductionProcess.AbortProcess();
|
||||
return;
|
||||
}
|
||||
|
||||
// References to commonly used production process objects
|
||||
process.Meter = _genesisMeter;
|
||||
process.RegisterRestorer = _registerRestorer;
|
||||
process.RadioEncryptionKey = _radioEncryptionKey;
|
||||
process.PwdContainer = _pwdContainer;
|
||||
process.ProductionStatus = _productionStatus;
|
||||
process.ProductionRequirements = _cordonelRequirements;
|
||||
process.EolProgress = _cordonelEolProgress;
|
||||
process.CancellationToken = _cancellationToken;
|
||||
processStateStruct.ProductionProcess.Meter = _genesisMeter;
|
||||
processStateStruct.ProductionProcess.RegisterRestorer = _registerRestorer;
|
||||
processStateStruct.ProductionProcess.RadioEncryptionKey = _radioEncryptionKey;
|
||||
processStateStruct.ProductionProcess.PwdContainer = _pwdContainer;
|
||||
processStateStruct.ProductionProcess.ProductionStatus = _productionStatus;
|
||||
processStateStruct.ProductionProcess.ProductionRequirements = _cordonelRequirements;
|
||||
processStateStruct.ProductionProcess.EolProgress = _cordonelEolProgress;
|
||||
processStateStruct.ProductionProcess.CancellationToken = _cancellationToken;
|
||||
|
||||
// kick off process execution, the breakExitState will not be used
|
||||
process.StartProcess(successExitState, errorExitState, breakExitState);
|
||||
processStateStruct.ProductionProcess.StartProcess(processStateStruct.NextStateOnSuccess,
|
||||
processStateStruct.ErrorExitState, processStateStruct.BreakExitState);
|
||||
// connect process events to actual process
|
||||
AddProcessEvents(process);
|
||||
AddProcessEvents(processStateStruct.ProductionProcess);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
/// </summary>
|
||||
RepeatFailedTests,
|
||||
/// <summary>
|
||||
/// Final test failed
|
||||
/// </summary>
|
||||
TestFailed,
|
||||
/// <summary>
|
||||
/// User stopped process
|
||||
/// </summary>
|
||||
Stop,
|
||||
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation for all production process states:
|
||||
/// - Production process class (representing a production process step),
|
||||
/// - attached state,
|
||||
/// - state information to display a text message.
|
||||
/// </summary>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public class EolProcessStates : BaseProcessStates
|
||||
{
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// - Setup state and state informal text,
|
||||
/// - Setup ProductionProcessFunctions, if these are null, it is just a state without any predefined function
|
||||
/// - Sort the active steps from first til last step as this is the order as those will be sorted in the
|
||||
/// process list UI.
|
||||
/// </summary>
|
||||
public EolProcessStates()
|
||||
{
|
||||
var stateContainer = new List<ProcessStateStruct>
|
||||
{
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.ReadyForShipping,
|
||||
Resources.StrStateReadyForShipping,
|
||||
null),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new DetectCordonel(Resources.StrStateDetectCordonel),
|
||||
ProcessState.DetectCordonel,
|
||||
Resources.StrStateDetectCordonel,
|
||||
0),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new ConnectCordonel(Resources.StrStateConnectCordonel),
|
||||
ProcessState.ConnectCordonel,
|
||||
Resources.StrStateConnectCordonel,
|
||||
1),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new GetSerialNumberAndRadioAddress(Resources.StrStateGetSerialAndRadioAddress),
|
||||
ProcessState.GetSerialNumberAndRadioAddress,
|
||||
Resources.StrStateGetSerialAndRadioAddress,
|
||||
2),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new GetFinalParametrization(Resources.StrStateGetProgrammingParameters),
|
||||
ProcessState.GetProgrammingParameters,
|
||||
Resources.StrStateGetProgrammingParameters,
|
||||
3),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new CheckProductionState(Resources.StrStateCheckProductionState),
|
||||
ProcessState.CheckProductionState,
|
||||
Resources.StrStateCheckProductionState,
|
||||
4),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new ExecPasswordFile(Resources.StrStatePasswordFile),
|
||||
ProcessState.ProcessPasswordFile,
|
||||
Resources.StrStatePasswordFile,
|
||||
5),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new ExecFinalParametrization(Resources.StrStateFinalParametrization),
|
||||
ProcessState.ExecFinalParametrization,
|
||||
Resources.StrStateFinalParametrization,
|
||||
6),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new ExecStoreConfiguration(Resources.StrStateStoreConfiguration),
|
||||
ProcessState.ExecStoreConfiguration,
|
||||
Resources.StrStateStoreConfiguration,
|
||||
7),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new ExecRebootCordonel(Resources.StrStateRebootCordonel),
|
||||
ProcessState.RebootCordonel,
|
||||
Resources.StrStateRebootCordonel,
|
||||
8),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new CheckFinalParametrization(Resources.StrStateCheckParametrization),
|
||||
ProcessState.CheckFinalParametrization,
|
||||
Resources.StrStateCheckParametrization,
|
||||
9),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new CheckRadio(Resources.StrStateRadioCheck),
|
||||
ProcessState.CheckRadio, Resources.StrStateRadioCheck,
|
||||
10),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
ProcessState.CheckOrderNumber,
|
||||
Resources.StrStateCheckOrderNumber,
|
||||
11),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
|
||||
ProcessState.CheckSerialNumber,
|
||||
Resources.StrStateCheckSerialNumber,
|
||||
12),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new CheckAttachments(Resources.StrStateCheckAttachments),
|
||||
ProcessState.CheckAttachments,
|
||||
Resources.StrStateCheckAttachments,
|
||||
13),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new VisualInspection(Resources.StrStateVisualInspection),
|
||||
ProcessState.ExecVisualInspection,
|
||||
Resources.StrStateVisualInspection,
|
||||
14),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new PrepareShipping(Resources.StrStatePrepareShipping),
|
||||
ProcessState.PrepareShippingMode,
|
||||
Resources.StrStatePrepareShipping,
|
||||
15)
|
||||
};
|
||||
StateContainer.AddRange(stateContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-14
@@ -44,7 +44,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2023-Jan-17" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public override void IndividualStateMachine(IProductionProcess process)
|
||||
public override void IndividualStateMachine(ProcessStateStruct processStateStruct)
|
||||
{
|
||||
switch (_stateMachineState)
|
||||
{
|
||||
@@ -53,8 +53,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
StartProcess(process, BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
waitForSingleProcess: _processStateDef?.GetProcessOfState(ProcessState.ConnectCordonel));
|
||||
StartProcess(processStateStruct);
|
||||
// Do not wait on completion as new parallel process can be started by manually state change.
|
||||
_stateMachineState = ProcessState.CheckProductionState;
|
||||
break;
|
||||
@@ -64,8 +63,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
StartProcess(process, BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
waitForSingleProcess: _processStateDef?.GetProcessOfState(ProcessState.ConnectCordonel));
|
||||
StartProcess(processStateStruct);
|
||||
// Do not wait on completion as new parallel process can be started by manually state change.
|
||||
_stateMachineState = ProcessState.ProcessPasswordFile;
|
||||
break;
|
||||
@@ -76,33 +74,33 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// effects on login. Wait for all processes to complete.
|
||||
// Leave state switch to automatic to avoid side effects on incomplete updated DB for next
|
||||
// steps.
|
||||
StartProcess(process, ProcessState.ExecFinalParametrization, waitForAllProcesses: true);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.ExecFinalParametrization:
|
||||
// This writes all setups to the device, it has to be executed exclusively with automatic
|
||||
StartProcess(process, ProcessState.ExecStoreConfiguration);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.ExecStoreConfiguration:
|
||||
// Precondition: - The final parametrization has to be finished as this shall be stored
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
// Store configuration has to be executed exclusively with automatic
|
||||
StartProcess(process, ProcessState.RebootCordonel);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.RebootCordonel:
|
||||
// Precondition: - The store configuration has to be executed to safe all settings
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
// Reboot has to be executed exclusively with automatic
|
||||
StartProcess(process, ProcessState.CheckFinalParametrization);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.CheckFinalParametrization:
|
||||
// Precondition: - The reboot process including the store all configurations has to be
|
||||
// completed.
|
||||
// Check final configuration has to be executed exclusively with automatic
|
||||
StartProcess(process, ProcessState.CheckRadio);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.CheckRadio:
|
||||
@@ -110,22 +108,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// configurations and the check of all setups survived the reboot have to be completed.
|
||||
// Radio signal level check, skipped on NA region or if skipping is required by special
|
||||
// approval
|
||||
StartProcess(process, ProcessState.CheckOrderNumber);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.CheckAttachments:
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
StartProcess(process, ProcessState.ExecVisualInspection);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.ExecVisualInspection:
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
StartProcess(process, ProcessState.PrepareShippingMode);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.PrepareShippingMode:
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
StartProcess(process, ProcessState.ReadyForShipping);
|
||||
StartProcess(processStateStruct);
|
||||
break;
|
||||
|
||||
case ProcessState.ReadyForShipping:
|
||||
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
using System.Collections.Generic;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation for all production process states:
|
||||
/// - Production process class (representing a production process step),
|
||||
/// - attached state,
|
||||
/// - state information to display a text message.
|
||||
/// </summary>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public class EolStateMachineCtrl : BaseProcessStates
|
||||
{
|
||||
/// <summary>
|
||||
/// State-machine definitions of production-processes which feeds the state-machine.
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR NORMAL USAGE:
|
||||
/// -----------------------------
|
||||
///
|
||||
/// If a special state is needed on errorExitState or breakExitState these can be assigned. Otherwise, the
|
||||
/// "errorExitState" is linked to the generic-error-state, the "breakExitState" to the abort-test-state.
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION FOR NON-BLOCKING MULTIPLE PROCESSES SIMULTANEOUSLY ACTIVITIES:
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Sometimes production processes may be able to be executed simultaneously as they are independent of each
|
||||
/// other. One example is a database access for data collection from different tables.
|
||||
///
|
||||
/// This is needed for non-blocking immediately new state change (not waiting for the successful execution of
|
||||
/// the actual new assigned process):
|
||||
/// E.g. all DB accesses need a certain time to get data, kicking off (fire and forget) the process without
|
||||
/// waiting for the result, the "nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion"
|
||||
/// has to be set to avoid a state change on successfully execution of the process.
|
||||
/// Instead, the "kickOffParallelState" has to be defined to immediately start the next process.
|
||||
///
|
||||
///
|
||||
/// INSTRUCTION TO DELAY THE START OF A PROCESS:
|
||||
/// --------------------------------------------
|
||||
/// Each new process execution can be delayed as it may need the result of another process which is active.
|
||||
///
|
||||
/// Wait for a single process to complete:
|
||||
/// - set the "waitForSingleProcess" to the process-state to wait for.
|
||||
///
|
||||
/// Wait for all preceding processes to complete:
|
||||
/// - set the "waitForAllProcesses" to true.
|
||||
///
|
||||
/// </summary>
|
||||
public EolStateMachineCtrl()
|
||||
{
|
||||
var stateContainer = new List<ProcessStateStruct>
|
||||
{
|
||||
#region ----------------------------------- GENERIC-STATES---------------------------------------------
|
||||
// Usage of the generic-state to detect the Cordonel on the communication line (request protocol)
|
||||
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
|
||||
// to change the state after successfully execution. The detection is the base for all others.
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
|
||||
processState: ProcessState.DetectCordonel,
|
||||
processInfo: Resources.StrStateDetectCordonel,
|
||||
productionProcessNo: 0,
|
||||
nextStateOnSuccess: ProcessState.CheckNewMeter),
|
||||
|
||||
// Usage of the generic-state to check for new meter
|
||||
// Detection of Cordonel has to be completed before assigning next state. It has to be checked if
|
||||
// the meter changed to clear all collected contents of previous run. To UPDATE ALL INFORMATION after
|
||||
// new meter assignment the "DetectCordonel" has to be repeated to return here "Old Meter" and then
|
||||
// enter the "ConnectCordonel"!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: null,
|
||||
processState: ProcessState.CheckNewMeter,
|
||||
processInfo: Resources.StrProcessStateCheckNewMeter,
|
||||
productionProcessNo: null,
|
||||
nextStateOnSuccess: ProcessState.DetectCordonel,
|
||||
errorExitState: ProcessState.ConnectCordonel),
|
||||
|
||||
// Usage of the generic-state to connect the Cordonel
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
|
||||
processState: ProcessState.ConnectCordonel,
|
||||
processInfo: Resources.StrStateConnectCordonel,
|
||||
productionProcessNo: 1,
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.GetSerialNumberAndRadioAddress),
|
||||
|
||||
// Usage of the generic-state to get the serial-number and radio-address
|
||||
// Precondition: - The detection process has to be completed as the PcbId is needed.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new GetSerialNumberAndRadioAddress(Resources.StrStateGetSerialAndRadioAddress),
|
||||
processState:ProcessState.GetSerialNumberAndRadioAddress,
|
||||
processInfo:Resources.StrStateGetSerialAndRadioAddress,
|
||||
productionProcessNo: 2,
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState:ProcessState.GetProgrammingParameters),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- EOL-STATES ------------------------------------------------
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new GetFinalParametrization(Resources.StrStateGetProgrammingParameters),
|
||||
processState: ProcessState.GetProgrammingParameters,
|
||||
processInfo: Resources.StrStateGetProgrammingParameters,
|
||||
productionProcessNo: 3,
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.CheckProductionState,
|
||||
// Wait until this process has been successfully completed
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
// AVOID to change the process state on completion as parallel process is active!
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
|
||||
processState: ProcessState.CheckProductionState,
|
||||
processInfo: Resources.StrStateCheckProductionState,
|
||||
productionProcessNo: 4,
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.ProcessPasswordFile,
|
||||
// Wait until this process has been successfully completed
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The connection process has to be completed as a password change in the DB
|
||||
// will take place: Skeleton to Password Level 8. Not waiting for completion may cause side
|
||||
// effects on login. Wait for all processes to complete.
|
||||
// Leave state switch to automatic to avoid side effects on incomplete updated DB for next
|
||||
// steps.
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecPasswordFile(Resources.StrStatePasswordFile),
|
||||
processState: ProcessState.ProcessPasswordFile,
|
||||
processInfo: Resources.StrStatePasswordFile,
|
||||
productionProcessNo: 5,
|
||||
nextStateOnSuccess: ProcessState.ExecFinalParametrization,
|
||||
waitForAllProcesses: true),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// This writes all setups to the device, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecFinalParametrization(Resources.StrStateFinalParametrization),
|
||||
processState: ProcessState.ExecFinalParametrization,
|
||||
processInfo: Resources.StrStateFinalParametrization,
|
||||
productionProcessNo: 6,
|
||||
nextStateOnSuccess: ProcessState.ExecStoreConfiguration),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The final parametrization has to be finished as this shall be stored
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
// Store configuration has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecStoreConfiguration(Resources.StrStateStoreConfiguration),
|
||||
processState: ProcessState.ExecStoreConfiguration,
|
||||
processInfo: Resources.StrStateStoreConfiguration,
|
||||
productionProcessNo: 7,
|
||||
nextStateOnSuccess: ProcessState.RebootCordonel),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The store configuration has to be executed to safe all settings
|
||||
// to non-volatile memory and checked if remaining valid after the reboot.
|
||||
// Reboot has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new ExecRebootCordonel(Resources.StrStateRebootCordonel),
|
||||
processState: ProcessState.RebootCordonel,
|
||||
processInfo: Resources.StrStateRebootCordonel,
|
||||
productionProcessNo: 8,
|
||||
nextStateOnSuccess: ProcessState.CheckFinalParametrization),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The reboot process including the store all configurations has to be
|
||||
// completed.
|
||||
// Check final configuration has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckFinalParametrization(Resources.StrStateCheckParametrization),
|
||||
ProcessState.CheckFinalParametrization,
|
||||
Resources.StrStateCheckParametrization,
|
||||
9,
|
||||
ProcessState.CheckRadio),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - The final parametrization, reboot process including the store all
|
||||
// configurations and the check of all setups survived the reboot have to be completed.
|
||||
// Radio signal level check, skipped on NA region or if skipping is required by special
|
||||
// approval
|
||||
new ProcessStateStruct(
|
||||
new CheckRadio(Resources.StrStateRadioCheck),
|
||||
ProcessState.CheckRadio,
|
||||
Resources.StrStateRadioCheck,
|
||||
10,
|
||||
ProcessState.CheckOrderNumber),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
ProcessState.CheckOrderNumber,
|
||||
Resources.StrStateCheckOrderNumber,
|
||||
11,
|
||||
ProcessState.CheckSerialNumber),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// This scans the serial number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
|
||||
ProcessState.CheckSerialNumber,
|
||||
Resources.StrStateCheckSerialNumber,
|
||||
12,
|
||||
ProcessState.CheckAttachments),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
new CheckAttachments(Resources.StrStateCheckAttachments),
|
||||
ProcessState.CheckAttachments,
|
||||
Resources.StrStateCheckAttachments,
|
||||
13,
|
||||
ProcessState.ExecVisualInspection),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
new VisualInspection(Resources.StrStateVisualInspection),
|
||||
ProcessState.ExecVisualInspection,
|
||||
Resources.StrStateVisualInspection,
|
||||
14,
|
||||
ProcessState.PrepareShippingMode),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
new PrepareShipping(Resources.StrStatePrepareShipping),
|
||||
ProcessState.PrepareShippingMode,
|
||||
Resources.StrStatePrepareShipping,
|
||||
15,
|
||||
ProcessState.ReadyForShipping),
|
||||
|
||||
// EOL-state of the EOL software
|
||||
new ProcessStateStruct(
|
||||
productionProcess: null,
|
||||
processState:ProcessState.ReadyForShipping,
|
||||
processInfo:Resources.StrStateReadyForShipping,
|
||||
productionProcessNo:null,
|
||||
nextStateOnSuccess:ProcessState.Idle),
|
||||
#endregion -------------------------------- EOL-STATES ------------------------------------------------
|
||||
|
||||
};
|
||||
StateContainer.AddRange(stateContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
+65
-55
@@ -27,78 +27,88 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// </summary>
|
||||
protected BaseProcessStates()
|
||||
{
|
||||
StateContainer = new List<ProcessStateStruct>
|
||||
StateContainer = new List<ProcessStateStruct>
|
||||
{
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.Idle,
|
||||
Resources.StrStateIdle,
|
||||
null),
|
||||
productionProcess: null,
|
||||
processState: ProcessState.Idle,
|
||||
processInfo: Resources.StrStateIdle,
|
||||
productionProcessNo: null,
|
||||
nextStateOnSuccess: ProcessState.Idle),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.CheckNewMeter,
|
||||
Resources.StrProcessStateCheckNewMeter,
|
||||
null),
|
||||
productionProcess: new ErrorHandler(null),
|
||||
processState: ProcessState.Error,
|
||||
processInfo: Resources.StrProcessStateError,
|
||||
productionProcessNo: null,
|
||||
nextStateOnSuccess: ProcessState.Idle,
|
||||
startAlways: true),
|
||||
|
||||
new ProcessStateStruct(
|
||||
new ErrorHandler(null),
|
||||
ProcessState.Error,
|
||||
Resources.StrProcessStateError,
|
||||
null),
|
||||
productionProcess: null,
|
||||
processState: ProcessState.RepeatFailedTests,
|
||||
processInfo: Resources.StrStateRepeatFinalTest,
|
||||
productionProcessNo: null,
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.RepeatFailedTests,
|
||||
Resources.StrStateRepeatFinalTest,
|
||||
null),
|
||||
productionProcess: null,
|
||||
processState:ProcessState.AbortTest,
|
||||
processInfo:Resources.StrStateSkipping,
|
||||
productionProcessNo:null,
|
||||
nextStateOnSuccess:ProcessState.Idle),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.AbortTest,
|
||||
Resources.StrStateSkipping,
|
||||
null),
|
||||
productionProcess: null,
|
||||
processState:ProcessState.Stop,
|
||||
processInfo:Resources.StrStateUserStop,
|
||||
productionProcessNo:null,
|
||||
nextStateOnSuccess:ProcessState.Idle),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.Stop,
|
||||
Resources.StrStateUserStop,
|
||||
null),
|
||||
productionProcess: null,
|
||||
processState:ProcessState.PrintSuccessReport,
|
||||
processInfo:Resources.StrStatePrintSuccessReport,
|
||||
productionProcessNo:null,
|
||||
nextStateOnSuccess:ProcessState.Idle),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.TestFailed,
|
||||
Resources.StrStateFinalTestFailed,
|
||||
null),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.PrintSuccessReport,
|
||||
Resources.StrStatePrintSuccessReport,
|
||||
null),
|
||||
|
||||
new ProcessStateStruct(
|
||||
null,
|
||||
ProcessState.PrintReturnReport,
|
||||
Resources.StrStatePrintReturnReport,
|
||||
null),
|
||||
|
||||
productionProcess: null,
|
||||
processState:ProcessState.PrintReturnReport,
|
||||
processInfo:Resources.StrStatePrintReturnReport,
|
||||
productionProcessNo:null,
|
||||
nextStateOnSuccess:ProcessState.Idle)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the process start struct linked to state of state machine
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>process state struct of the attached state</returns>
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public ProcessStateStruct GetProcessStateStructOfState(ProcessState stateMachineState)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
where stateContainer.ProcessState == stateMachineState
|
||||
select stateContainer).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the process linked to state of state machine
|
||||
/// </summary>
|
||||
/// <param name="stateMachineState">state to search for information text</param>
|
||||
/// <returns>process attached to state</returns>
|
||||
/// <returns>process attached to the state</returns>
|
||||
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public IProductionProcess GetProcessOfState(ProcessState stateMachineState)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
where stateContainer.State == stateMachineState
|
||||
select stateContainer.Process).FirstOrDefault();
|
||||
where stateContainer.ProcessState == stateMachineState
|
||||
select stateContainer.ProductionProcess).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -118,8 +128,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
stateMachineState = ProcessState.Error;
|
||||
|
||||
return (from stateContainer in StateContainer
|
||||
where stateContainer.State == stateMachineState
|
||||
select stateContainer.Info).FirstOrDefault();
|
||||
where stateContainer.ProcessState == stateMachineState
|
||||
select stateContainer.ProcessInfo).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -133,8 +143,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
public String GetStateInfoOfProcess(IProductionProcess process)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
where stateContainer.Process == process
|
||||
select stateContainer.Info).FirstOrDefault();
|
||||
where stateContainer.ProductionProcess == process
|
||||
select stateContainer.ProcessInfo).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -148,8 +158,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
public ProcessState GetStateOfInfoText(String text)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
where stateContainer.Info == text
|
||||
select stateContainer.State).FirstOrDefault();
|
||||
where stateContainer.ProcessInfo == text
|
||||
select stateContainer.ProcessState).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -163,8 +173,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
public ProcessState GetStateOfProcess(IProductionProcess process)
|
||||
{
|
||||
return (from stateContainer in StateContainer
|
||||
where stateContainer.Process == process
|
||||
select stateContainer.State).FirstOrDefault();
|
||||
where stateContainer.ProductionProcess == process
|
||||
select stateContainer.ProcessState).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -183,7 +193,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all EOL relevant states
|
||||
/// Get a sorted list of all production processes in order of the execution sequence
|
||||
/// </summary>
|
||||
/// <returns>list of initialized processes</returns>
|
||||
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
|
||||
@@ -200,7 +210,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
var sortedList = StateContainer
|
||||
.Where(y => y.ProductionProcessNo != null)
|
||||
.OrderBy(x => x.ProductionProcessNo);
|
||||
return (from state in sortedList select state.Process).ToList();
|
||||
return (from state in sortedList select state.ProductionProcess).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// Individual states to fill the state machine.
|
||||
/// ATTENTION: All states have to be part of the <see cref="ProcessState"/>
|
||||
/// </summary>
|
||||
void IndividualStateMachine(IProductionProcess process);
|
||||
void IndividualStateMachine(ProcessStateStruct processStateStruct);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,45 +4,105 @@ using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenation between final test state and text
|
||||
/// Concatenation between test state and text feeding the state machine with next state.
|
||||
/// </summary>
|
||||
public struct ProcessStateStruct
|
||||
{
|
||||
/// <summary>
|
||||
/// Assign process state information
|
||||
/// </summary>
|
||||
/// <param name="process">production process, set to null for "invisible" states</param>
|
||||
/// <param name="state">assigned state for call of this process used by the state machine</param>
|
||||
/// <param name="info">name for process to display a message in the GUI</param>
|
||||
/// <param name="productionProcess">production process, set to null for "invisible" states</param>
|
||||
/// <param name="processState">assigned state for call of this process used by the state machine</param>
|
||||
/// <param name="processInfo">name for process to display a message in the GUI</param>
|
||||
/// <param name="productionProcessNo">set a unique number to sort the table of production processes,
|
||||
/// set to null for all hidden processes which are not a production process</param>
|
||||
/// <param name="nextStateOnSuccess">BaseProductionProcess.DoNotChangeStateAfterCompletion will not
|
||||
/// change the state automatically</param>
|
||||
/// <param name="errorExitState"></param>
|
||||
/// <param name="breakExitState"></param>
|
||||
/// <param name="kickOffParallelState">start a parallel process</param>
|
||||
/// <param name="waitForSingleProcess">wait for single processes to complete before execution</param>
|
||||
/// <param name="waitForAllProcesses">wait for all processes to complete before execution</param>
|
||||
/// <param name="startAlways">start even if abort is required</param>
|
||||
/// <remarks date="2023-Jan-17" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
public ProcessStateStruct(IProductionProcess process, ProcessState state, String info,
|
||||
UInt32? productionProcessNo)
|
||||
/// <remarks date="2025-Apr-14" author="Thomas Wiedebusch">
|
||||
/// - Extended to steer state machine with this struct.
|
||||
/// </remarks>
|
||||
public ProcessStateStruct(IProductionProcess productionProcess, ProcessState processState, String processInfo,
|
||||
UInt32? productionProcessNo, ProcessState? nextStateOnSuccess, ProcessState errorExitState = ProcessState.Error,
|
||||
ProcessState breakExitState = ProcessState.Stop,
|
||||
ProcessState? kickOffParallelState = null,
|
||||
ProcessState? waitForSingleProcess = null,
|
||||
Boolean waitForAllProcesses = false, Boolean startAlways = false)
|
||||
{
|
||||
Process = process;
|
||||
State = state;
|
||||
Info = info;
|
||||
ProductionProcess = productionProcess;
|
||||
ProcessState = processState;
|
||||
ProcessInfo = processInfo;
|
||||
ProductionProcessNo = productionProcessNo;
|
||||
NextStateOnSuccess = nextStateOnSuccess;
|
||||
ErrorExitState = errorExitState;
|
||||
BreakExitState = breakExitState;
|
||||
KickOffParallelState = kickOffParallelState;
|
||||
WaitForSingleProcess = waitForSingleProcess;
|
||||
WaitForAllProcesses = waitForAllProcesses;
|
||||
StartAlways = startAlways;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a parallel process
|
||||
/// </summary>
|
||||
public ProcessState? KickOffParallelState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The state of the final test
|
||||
/// </summary>
|
||||
public IProductionProcess Process { get; }
|
||||
public IProductionProcess ProductionProcess { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The state of the final test
|
||||
/// </summary>
|
||||
public ProcessState State { get; }
|
||||
public ProcessState ProcessState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The info message of the state
|
||||
/// </summary>
|
||||
public String Info { get; }
|
||||
public String ProcessInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes which are relevant for the production have a number for the sequence they should be displayed
|
||||
/// in the GUI, all hidden (non-)production processes are set to null
|
||||
/// </summary>
|
||||
public UInt32? ProductionProcessNo { get; }
|
||||
public UInt32? ProductionProcessNo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Next state required after successfully execution
|
||||
/// </summary>
|
||||
public ProcessState? NextStateOnSuccess { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Special state used for error or for the second output of the process
|
||||
/// </summary>
|
||||
public ProcessState ErrorExitState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Special state required on user break
|
||||
/// </summary>
|
||||
public ProcessState BreakExitState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Wait for a single process named here to take the result into account
|
||||
/// </summary>
|
||||
public ProcessState? WaitForSingleProcess { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Wait until all preceding processes are finished with success
|
||||
/// </summary>
|
||||
public Boolean WaitForAllProcesses { get; }
|
||||
/// <summary>
|
||||
/// Sate which has to be active always even if a predecessor failed (e.g. error state)
|
||||
/// </summary>
|
||||
public Boolean StartAlways { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@
|
||||
<Compile Include="Model\EOLHandler.cs" />
|
||||
<Compile Include="ProductionProcesses\Enum\PickingProcessState.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\VisualInspection.cs" />
|
||||
<Compile Include="ProductionProcesses\BaseProcessStates.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericStateMachineCtrl.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\ErrorHandler.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\ExecStoreConfiguration.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\GetSerialNumberAndRadioAddress.cs" />
|
||||
@@ -300,7 +300,7 @@
|
||||
<Compile Include="ProductionProcesses\Enum\ImgState.cs" />
|
||||
<Compile Include="ProductionProcesses\Enum\ProcessState.cs" />
|
||||
<Compile Include="ProductionProcesses\EventArgs\SingleProcessStateArgs.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\EolProcessStates.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\EolStateMachineCtrl.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\EolStateMachine.cs" />
|
||||
<Compile Include="ProductionProcesses\IProcessController.cs" />
|
||||
<Compile Include="ProductionProcesses\IProcessStates.cs" />
|
||||
|
||||
Reference in New Issue
Block a user