ProductionUiCordonel: - re-organized to support multiple production processes part 3

This commit is contained in:
Thomas Wiedebusch
2025-04-14 16:07:27 +02:00
parent 8909602dac
commit cf8a0b90b4
6 changed files with 232 additions and 205 deletions
@@ -21,7 +21,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
{
#region ------------------------------------------ Variables --------------------------------------------------
// actual genesis meter
protected IGenesisMeter _genesisMeter;
private IGenesisMeter _genesisMeter;
// Cordonel requirements for production
private CordonelRequirements _cordonelRequirements;
// EOL progress states for production
@@ -33,9 +33,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
// state of the state machine
protected ProcessState _stateMachineState;
// locker to avoid repeated state execution
protected ProcessState _lockedProcessState;
private ProcessState _lockedProcessState;
// sender of state change event to evaluate in e.g. error process
protected IProductionProcess _stateChangeRequestProcess;
private IProductionProcess _stateChangeRequestProcess;
// List of production processes
public List<IProductionProcess> Processes
{
@@ -44,7 +44,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
}
// Container for production process states
protected EolProcessStates _processStateDef;
protected BaseProcessStates _processStateDef;
// Container for production status information, a list is used to keep the content over all classes of production
// processes as a reference seems not to return their value (always reset to the initial value)
@@ -87,12 +87,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
public event EventHandler<ProcessProgressArgs> OnProcessProgressChanged;
// cancellation token
protected CancellationTokenSource _cancellationTokenSource;
protected CancellationToken _cancellationToken;
private CancellationTokenSource _cancellationTokenSource;
private CancellationToken _cancellationToken;
// cyclic timer for state machine call
private Timer _processCtrlTimer;
protected const Int32 ProcessTimerCycleMs = 250;
private const Int32 ProcessTimerCycleMs = 250;
// defines for state machine
/// <summary>
@@ -253,21 +253,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
{
OnProcessLogRequest?.Invoke(sender, e);
}
/// <summary>
/// Wrapper to fire this event from a derived class
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks date="2025-Apr-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
protected void OverallProcessStateChanged(Object sender, ProcessStateArgs e)
{
// signal state change to logger
OnOverallProcessStateChanged?.Invoke(sender, e);
}
/// <summary>
/// Handler to set a new state for the state machine regarding the entire final-process
/// </summary>
@@ -374,7 +359,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
CalcAndPushOverAllProgress();
// signal state change to logger
OverallProcessStateChanged(this, new ProcessStateArgs(_stateMachineState));
OnOverallProcessStateChanged?.Invoke(this, new ProcessStateArgs(_stateMachineState));
// get the actual required process from the state definition list
var process = _processStateDef?.GetProcessOfState(_stateMachineState);
@@ -531,7 +516,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
/// - Handle genesis meter is null as new meter.
/// </remarks>
protected Boolean CheckForNewMeter()
private Boolean CheckForNewMeter()
{
if (_genesisMeter == null ||
(!string.IsNullOrEmpty(_lastPcbId) &&
@@ -569,7 +554,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <remarks date="2024-Oct-21" author="Thomas Wiedebusch">
/// - Leave skipped processes as is.
/// </remarks>
protected ProcessState RepeatFailedTests()
private ProcessState RepeatFailedTests()
{
var state = ProcessState.Idle;
@@ -611,7 +596,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <remarks date="2025-Jan-28" author="Thomas Wiedebusch">
/// - Kick off exec parametrization if check after reboot failed.
/// </remarks>
protected void ProcessErrorHandler(IProductionProcess process)
private void ProcessErrorHandler(IProductionProcess process)
{
if (process == null)
return;
@@ -636,7 +621,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <summary>
/// Calculate the maximum of all processes expected to execute and signal to GUI.
/// </summary>
protected void CalcAndPushMaxOverAllProcessSteps()
private void CalcAndPushMaxOverAllProcessSteps()
{
if (_processStateDef == null)
return;
@@ -650,7 +635,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <summary>
/// Calculate all processes which are completed or skipped and signal to GUI.
/// </summary>
protected void CalcAndPushOverAllProgress()
private void CalcAndPushOverAllProgress()
{
if (Processes == null)
return;
@@ -899,7 +884,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <remarks date="2025-Apr-07" author="Thomas Wiedebusch">
/// - Cancellation token source.
/// </remarks>
protected void KillProcesses()
private void KillProcesses()
{
_cancellationTokenSource?.Cancel();
Thread.Sleep(1000);
@@ -921,7 +906,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
/// <remarks date="2023-Jun-21" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
protected void AbortProcesses()
private void AbortProcesses()
{
if (Processes == null || Processes.Count == 0)
return;
@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
{
/// <summary>
/// Concatenation for all production process states:
/// </summary>
/// <remarks date="2025-Apr-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public class BaseProcessStates : IProcessStates
{
/// <summary>
/// Collection of state information
/// </summary>
protected List<ProcessStateStruct> StateContainer { set; get; }
/// <summary>
/// Ctor
/// </summary>
protected BaseProcessStates()
{
}
/// <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>
/// <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();
}
/// <summary>
/// Get the current information of the state machine state
/// </summary>
/// <param name="stateMachineState">state to search for information text</param>
/// <returns>information attached to state depending on region</returns>
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2024-Mar-18" author="Thomas Wiedebusch">
/// - If state == null return error message.
/// </remarks>
public String GetStateInfoOfState(ProcessState? stateMachineState)
{
if (stateMachineState == null)
stateMachineState = ProcessState.Error;
return (from stateContainer in StateContainer
where stateContainer.State == stateMachineState
select stateContainer.Info).FirstOrDefault();
}
/// <summary>
/// Get the info text from production process
/// </summary>
/// <param name="process">process to look for state info text</param>
/// <returns>information attached to process depending on region</returns>
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public String GetStateInfoOfProcess(IProductionProcess process)
{
return (from stateContainer in StateContainer
where stateContainer.Process == process
select stateContainer.Info).FirstOrDefault();
}
/// <summary>
/// Get the state machine state of the text
/// </summary>
/// <param name="text">information text to search if state is assigned</param>
/// <returns>state attached to information text</returns>
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public ProcessState GetStateOfInfoText(String text)
{
return (from stateContainer in StateContainer
where stateContainer.Info == text
select stateContainer.State).FirstOrDefault();
}
/// <summary>
/// Get the state machine state from for the process
/// </summary>
/// <param name="process">process to look for state info text</param>
/// <returns>state attached to process</returns>
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public ProcessState GetStateOfProcess(IProductionProcess process)
{
return (from stateContainer in StateContainer
where stateContainer.Process == process
select stateContainer.State).FirstOrDefault();
}
/// <summary>
/// Get number of EOL relevant processes for statistic e.g. progress bar
/// </summary>
/// <returns>number of initialized processes</returns>
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
/// - Used marker for production relevant processes
/// </remarks>
public Int32 GetNumberOfInitializedProcesses()
{
return StateContainer.Count(stateContainer => stateContainer.ProductionRelevant );
}
/// <summary>
/// Get all EOL relevant states
/// </summary>
/// <returns>list of initialized processes</returns>
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
/// - Used marker for production relevant processes
/// </remarks>
public List<IProductionProcess> GetAllEolRelevantProcesses()
{
return (from state in StateContainer where state.ProductionRelevant
select state.Process).ToList();
}
}
}
@@ -16,13 +16,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public class EolProcessStates
public class EolProcessStates : BaseProcessStates
{
/// <summary>
/// Collection of state information
/// </summary>
private readonly List<ProcessStateStruct> _stateContainer;
/// <summary>
/// Ctor
/// - Setup state and state informal text,
@@ -32,154 +27,154 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
/// </summary>
public EolProcessStates()
{
_stateContainer = new List<ProcessStateStruct>
StateContainer = new List<ProcessStateStruct>
{
new ProcessStateStruct(
null,
ProcessState.Idle,
null,
ProcessState.Idle,
Resources.StrStateIdle,
false),
new ProcessStateStruct(
null,
ProcessState.CheckNewMeter,
null,
ProcessState.CheckNewMeter,
Resources.StrProcessStateCheckNewMeter,
false),
new ProcessStateStruct(
new ErrorHandler(null),
ProcessState.Error,
new ErrorHandler(null),
ProcessState.Error,
Resources.StrProcessStateError,
false),
new ProcessStateStruct(
null,
null,
ProcessState.RepeatFailedTests,
Resources.StrStateRepeatFinalTest,
false),
new ProcessStateStruct(
null,
ProcessState.AbortTest,
null,
ProcessState.AbortTest,
Resources.StrStateSkipping,
false),
new ProcessStateStruct(
null,
ProcessState.Stop,
null,
ProcessState.Stop,
Resources.StrStateUserStop,
false),
new ProcessStateStruct(
null,
ProcessState.TestFailed,
null,
ProcessState.TestFailed,
Resources.StrStateFinalTestFailed,
false),
new ProcessStateStruct(
null,
ProcessState.ReadyForShipping,
null,
ProcessState.ReadyForShipping,
Resources.StrStateReadyForShipping,
false),
new ProcessStateStruct(
null,
ProcessState.PrintSuccessReport,
null,
ProcessState.PrintSuccessReport,
Resources.StrStatePrintSuccessReport,
false),
new ProcessStateStruct(
null,
ProcessState.PrintReturnReport,
null,
ProcessState.PrintReturnReport,
Resources.StrStatePrintReturnReport,
false),
new ProcessStateStruct(
new DetectCordonel(Resources.StrStateDetectCordonel),
new DetectCordonel(Resources.StrStateDetectCordonel),
ProcessState.DetectCordonel,
Resources.StrStateDetectCordonel,
true),
new ProcessStateStruct(
new ConnectCordonel(Resources.StrStateConnectCordonel),
new ConnectCordonel(Resources.StrStateConnectCordonel),
ProcessState.ConnectCordonel,
Resources.StrStateConnectCordonel,
true),
new ProcessStateStruct(
new GetSerialNumberAndRadioAddress(Resources.StrStateGetSerialAndRadioAddress),
new GetSerialNumberAndRadioAddress(Resources.StrStateGetSerialAndRadioAddress),
ProcessState.GetSerialNumberAndRadioAddress,
Resources.StrStateGetSerialAndRadioAddress,
true),
new ProcessStateStruct(
new GetFinalParametrization(Resources.StrStateGetProgrammingParameters),
ProcessState.GetProgrammingParameters,
ProcessState.GetProgrammingParameters,
Resources.StrStateGetProgrammingParameters,
true),
new ProcessStateStruct(
new CheckProductionState(Resources.StrStateCheckProductionState),
ProcessState.CheckProductionState,
Resources.StrStateCheckProductionState,
true),
new ProcessStateStruct(
new ExecPasswordFile(Resources.StrStatePasswordFile),
ProcessState.ProcessPasswordFile,
Resources.StrStatePasswordFile,
true),
new ProcessStateStruct(
new ExecFinalParametrization(Resources.StrStateFinalParametrization),
ProcessState.ExecFinalParametrization,
ProcessState.ExecFinalParametrization,
Resources.StrStateFinalParametrization,
true),
new ProcessStateStruct(
new ExecStoreConfiguration(Resources.StrStateStoreConfiguration),
ProcessState.ExecStoreConfiguration,
ProcessState.ExecStoreConfiguration,
Resources.StrStateStoreConfiguration,
true),
new ProcessStateStruct(
new ExecRebootCordonel(Resources.StrStateRebootCordonel),
ProcessState.RebootCordonel,
ProcessState.RebootCordonel,
Resources.StrStateRebootCordonel,
true),
new ProcessStateStruct(
new CheckFinalParametrization(Resources.StrStateCheckParametrization),
ProcessState.CheckFinalParametrization,
Resources.StrStateCheckParametrization,
true),
new ProcessStateStruct(
new CheckRadio(Resources.StrStateRadioCheck),
ProcessState.CheckRadio, Resources.StrStateRadioCheck,
true),
new ProcessStateStruct(
new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
ProcessState.CheckOrderNumber,
ProcessState.CheckOrderNumber,
Resources.StrStateCheckOrderNumber,
true),
new ProcessStateStruct(
new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
ProcessState.CheckSerialNumber,
Resources.StrStateCheckSerialNumber,
true),
new ProcessStateStruct(
new CheckAttachments(Resources.StrStateCheckAttachments),
ProcessState.CheckAttachments,
ProcessState.CheckAttachments,
Resources.StrStateCheckAttachments,
true),
new ProcessStateStruct(
new VisualInspection(Resources.StrStateVisualInspection),
ProcessState.ExecVisualInspection,
ProcessState.ExecVisualInspection,
Resources.StrStateVisualInspection,
true),
@@ -190,117 +185,5 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
true)
};
}
/// <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>
/// <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();
}
/// <summary>
/// Get the current information of the state machine state
/// </summary>
/// <param name="stateMachineState">state to search for information text</param>
/// <returns>information attached to state depending on region</returns>
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2024-Mar-18" author="Thomas Wiedebusch">
/// - If state == null return error message.
/// </remarks>
public String GetStateInfoOfState(ProcessState? stateMachineState)
{
if (stateMachineState == null)
stateMachineState = ProcessState.Error;
return (from stateContainer in _stateContainer
where stateContainer.State == stateMachineState
select stateContainer.Info).FirstOrDefault();
}
/// <summary>
/// Get the info text from production process
/// </summary>
/// <param name="process">process to look for state info text</param>
/// <returns>information attached to process depending on region</returns>
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public String GetStateInfoOfProcess(IProductionProcess process)
{
return (from stateContainer in _stateContainer
where stateContainer.Process == process
select stateContainer.Info).FirstOrDefault();
}
/// <summary>
/// Get the state machine state of the text
/// </summary>
/// <param name="text">information text to search if state is assigned</param>
/// <returns>state attached to information text</returns>
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public ProcessState GetStateOfInfoText(String text)
{
return (from stateContainer in _stateContainer
where stateContainer.Info == text
select stateContainer.State).FirstOrDefault();
}
/// <summary>
/// Get the state machine state from for the process
/// </summary>
/// <param name="process">process to look for state info text</param>
/// <returns>state attached to process</returns>
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public ProcessState GetStateOfProcess(IProductionProcess process)
{
return (from stateContainer in _stateContainer
where stateContainer.Process == process
select stateContainer.State).FirstOrDefault();
}
/// <summary>
/// Get number of EOL relevant processes for statistic e.g. progress bar
/// </summary>
/// <returns>number of initialized processes</returns>
/// <remarks date="2023-Mar-20" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
/// - Used marker for production relevant processes
/// </remarks>
public Int32 GetNumberOfInitializedProcesses()
{
return _stateContainer.Count(stateContainer => stateContainer.ProductionRelevant );
}
/// <summary>
/// Get all EOL relevant states
/// </summary>
/// <returns>list of initialized processes</returns>
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
/// <remarks date="2024-Sep-01" author="Thomas Wiedebusch">
/// - Used marker for production relevant processes
/// </remarks>
public List<IProductionProcess> GetAllEolRelevantProcesses()
{
return (from state in _stateContainer where state.ProductionRelevant
select state.Process).ToList();
}
}
}
}
@@ -1,7 +1,5 @@
using System;
using System.Threading;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs;
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
{
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Controls;
using LaaPackages.Features.Cordonel.Models;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EventArgs;
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
{
public interface IProcessStates
{
}
}
@@ -289,6 +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\GenericProcesses\ErrorHandler.cs" />
<Compile Include="ProductionProcesses\EolProcesses\ExecStoreConfiguration.cs" />
<Compile Include="ProductionProcesses\GenericProcesses\GetSerialNumberAndRadioAddress.cs" />
@@ -302,6 +303,7 @@
<Compile Include="ProductionProcesses\EolProcesses\EolProcessStates.cs" />
<Compile Include="ProductionProcesses\EolProcesses\EolStateMachine.cs" />
<Compile Include="ProductionProcesses\IProcessController.cs" />
<Compile Include="ProductionProcesses\IProcessStates.cs" />
<Compile Include="ProductionProcesses\ProcessStateStruct.cs" />
<Compile Include="Data\PickingResultData.cs" />
<Compile Include="Data\PressureResultDataNotifyable.cs" />