diff --git a/TBF/BenchControl/Sequences/MainSeq.cs b/TBF/BenchControl/Sequences/MainSeq.cs
index 0dbbfb828..339837d68 100644
--- a/TBF/BenchControl/Sequences/MainSeq.cs
+++ b/TBF/BenchControl/Sequences/MainSeq.cs
@@ -6,20 +6,17 @@ using System.Collections.Generic;
using System.Diagnostics;
using log4net;
using NHibernate;
-using Config;
using Config.Entities;
using Results.Entities;
-using TBF.UiBridge;
using TBF.BenchControl.Operations;
using TBF.BenchControl.GenericDevices;
using TBF.Boxes;
using TBF.Resources;
-using System.Threading;
-using System.IO;
+using TBF.UiBridge;
namespace TBF.BenchControl.Sequences
{
- public class MainSeq : SequenceBase
+ public partial class MainSeq : SequenceBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(MainSeq));
@@ -79,7 +76,9 @@ namespace TBF.BenchControl.Sequences
- /// Constructor
+ ///
+ /// Constructor
+ ///
public MainSeq()
{
benchFilled = false;
@@ -99,268 +98,8 @@ namespace TBF.BenchControl.Sequences
///
- /// Unconditionally wait for OK button
+ /// Main sequence execution
///
- void WaitForOkButton()
- {
- State.Create("MainSeq : Press OK to start the system")
- .AddOperation(new BenchControl.Operations.MessageBoxOp(Strings.Start_the_test_bench, System.Drawing.Color.OliveDrab))
- .EnterState();
-
- while (!StateMachine.WaitRunDevsRunOps().Contains(Event.OK)) { }
- }
-
-
- ///
- /// Unconditionally set valves to default position
- ///
- void SetValvesToDefaultState()
- {
- State.Create("MainSeq : Setting valves to default positions")
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose))
- .EnterState();
-
- while (StateMachine.WaitRunDevsRunOps().Contains(Event.ValvesBusy)) { }
- }
-
-
- ///
- /// Test communication with all scales that support S/N read operation
- ///
- /// Name of a scale that failed
- /// Message in case of a failure
- /// true = Test passed, all scales communicate OK
- bool TestCommunicationWithScales(out string scaleName, out string message)
- {
- ///
- /// Read S/N-s from scales (cannot be stopped, but is limitted to Scales count x 3s (=timeout)
- ///
- IScaleOrTank[] tanks = new IScaleOrTank[] { StateMachine.Tank1, StateMachine.Tank2, StateMachine.Tank3 };
-
- foreach (var tank in tanks)
- {
- if (tank is IScale)
- {
- IScale scale = tank as IScale;
- string sn = string.Empty;
- IOperation getSNOp = scale.GetSerNumOp(ref sn);
-
- if (getSNOp != null)
- {
- const int nrRetries = 3;
-
- for (int i = 1; i <= nrRetries; i++)
- {
- IList e;
- bool error = false;
- bool timeout = false;
-
- State.Create(string.Format("MainSeq : Reading S/N of scale {0} trial {1}", scale.Name, i))
- .AddOperation(getSNOp)
- .AddOperation(new Operations.TimerOp(2))
- .EnterState();
- do
- {
- e = StateMachine.WaitRunDevsRunOps();
- if (e.Contains(Event.Error))
- {
- if (i == nrRetries)
- {
- ///
- /// All retries completed => the scale failed
- ///
- scaleName = scale.Name;
- message = Strings.Scale_communication_error;
- return false;
- }
- else
- {
- /// The scale failed => try one more time
- error = true;
- break;
- }
- }
- if (e.Contains(Event.Busy) && e.Contains(Event.TimerExpired))
- {
- if (i == nrRetries)
- {
- ///
- /// All retries completed, the scale failed
- ///
- scaleName = scale.Name;
- message = Strings.Scale_communication_timeout;
- return false;
- }
- else
- {
- /// The scale failed => try one more time
- timeout = true;
- break;
- }
- }
- }
- while (e.Contains(Event.Busy));
-
- if (!error && !timeout)
- {
- /// This scale communicates OK, break "for (int i = ... " loop
- if (!string.IsNullOrEmpty(sn)) log.WarnFormat("Scale {0} : s/n = {1}", scale.Name, sn);
- break; ///
- }
-
- /// Wait one state machine tick (1 second), kreep retrying, stay inside "for (int i = ... " loop
- State.Create(string.Format("MainSeq : Reading S/N of scale {0}", scale.Name)).EnterState();
- StateMachine.WaitRunDevsRunOps();
- }
- }
- }
- }
-
- ///
- /// All scales communicate OK, test passed
- ///
- scaleName = string.Empty;
- message = string.Empty;
- return true;
- }
-
-
- ///
- ///
- ///
- /// true = OK, false = error
- bool DrainTanks()
- {
- IList e;
-
- ///
- /// Enable stop draining buttons
- ///
- Bridge.Bench2UI(((StateMachine.DrainValve1 != null) ? ButtonsEtc.DrainTankBtn1Hi : 0) |
- ((StateMachine.DrainValve2 != null) ? ButtonsEtc.DrainTankBtn2Hi : 0) |
- ((StateMachine.DrainValve3 != null) ? ButtonsEtc.DrainTankBtn3Hi : 0));
-
- ///
- /// Determine lists of drain valves and drain times (max. of all tank drain times)
- ///
- IList fullDrainValves = new List();
- IList secondHalfDrainValves = new List();
- IList allDrainValves = new List();
- int totalDrainTime = 0;
- int maxDrainTimeFor2VlvTanks = 0;
- bool areTwoDrainPhases = false;
- foreach (IScaleOrTank tank in new IScaleOrTank[] { StateMachine.Tank1, StateMachine.Tank2, StateMachine.Tank3 })
- {
- if (tank != null && tank.DrainValve != null)
- {
- if (tank.EmptyTimeSec > totalDrainTime) totalDrainTime = tank.EmptyTimeSec;
- if (tank.DrainValve2 != null)
- {
- areTwoDrainPhases = true;
- if (tank.EmptyTimeSec > maxDrainTimeFor2VlvTanks) maxDrainTimeFor2VlvTanks = tank.EmptyTimeSec;
-
- if (!secondHalfDrainValves.Contains(tank.DrainValve)) secondHalfDrainValves.Add(tank.DrainValve);
- if (!fullDrainValves.Contains(tank.DrainValve2)) fullDrainValves.Add(tank.DrainValve2);
- if (!allDrainValves.Contains(tank.DrainValve)) allDrainValves.Add(tank.DrainValve);
- if (!allDrainValves.Contains(tank.DrainValve2)) allDrainValves.Add(tank.DrainValve2);
- }
- else
- {
- if (!fullDrainValves.Contains(tank.DrainValve)) fullDrainValves.Add(tank.DrainValve);
- if (!allDrainValves.Contains(tank.DrainValve)) allDrainValves.Add(tank.DrainValve);
- }
- }
- }
-
- ///
- /// Drain the tanks, two phases if necessary
- ///
- if (totalDrainTime > 0)
- {
- IntBox timerTime = new IntBox(); /// Contains remaining time in each phase
- int firstPhaseTime = maxDrainTimeFor2VlvTanks / 2;
-
- State.Create(areTwoDrainPhases ? "MainSeq : Drain tanks - phase 1" : "MainSeq : Drain tanks")
- .AddOperation(checkUiOp)
- .AddOperation(new TimerOp(areTwoDrainPhases ? firstPhaseTime : totalDrainTime, timerTime))
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(fullDrainValves, null))
- .EnterState();
- do {
- int remTime = areTwoDrainPhases ? (timerTime.Val + totalDrainTime - firstPhaseTime) : timerTime.Val;
- Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remTime / 60, "min", remTime % 60, Strings.sec));
-
- e = StateMachine.WaitRunDevsRunOps();
- if (e.Contains(Event.Error)) return false;
- bool stopDrainingCmd = e.Contains(Event.UiCmdStopDrainingTank1) || e.Contains(Event.UiCmdStopDrainingTank2) || e.Contains(Event.UiCmdStopDrainingTank3);
- if (stopDrainingCmd && !e.Contains(Event.ValvesBusy) && !e.Contains(Event.CameraBusy)) break;
- }
- while (e.Contains(Event.TimerBusy) || e.Contains(Event.CameraBusy) || e.Contains(Event.ValvesBusy));
-
- if (areTwoDrainPhases)
- {
- State.Create("MainSeq : Drain tanks - phase 2")
- .AddOperation(checkUiOp)
- .AddOperation(new TimerOp(totalDrainTime - firstPhaseTime, timerTime))
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(secondHalfDrainValves, null))
- .EnterState();
- do {
- int remTime = timerTime.Val;
- Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remTime / 60, "min", remTime % 60, Strings.sec));
-
- e = StateMachine.WaitRunDevsRunOps();
- if (e.Contains(Event.Error)) return false;
- bool stopDrainingCmd = e.Contains(Event.UiCmdStopDrainingTank1) || e.Contains(Event.UiCmdStopDrainingTank2) || e.Contains(Event.UiCmdStopDrainingTank3);
- if (stopDrainingCmd && !e.Contains(Event.ValvesBusy) && !e.Contains(Event.CameraBusy)) break;
- }
- while (e.Contains(Event.TimerBusy) || e.Contains(Event.CameraBusy) || e.Contains(Event.ValvesBusy));
- }
-
- Bridge.OnActivity(this, Strings.Emptying_tank);
-
- State stopDraining = State.Create("MainSeq : Stop draining water tanks")
- .AddOperation(checkUiOp)
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(null, allDrainValves))
- .EnterState();
- do {
- e = StateMachine.WaitRunDevsRunOps();
- if (e.Contains(Event.Error)) return false;
- }
- while (e.Contains(Event.ValvesBusy));
- }
-
- return true; /// OK
- }
-
-
- ///
- /// This function is called after a procedure was selected and all components procedure parameters of components were loaded
- ///
- void ClearSessionData()
- {
- ///
- /// Clear iperlhead data (including PCB Number, avoid double use)
- ///
- foreach (var cmpnt in StateMachine.Components)
- {
- if (cmpnt is TestMethods.iPerlCommunication.iPerlHead.IperlHead)
- {
- (cmpnt as TestMethods.iPerlCommunication.iPerlHead.IperlHead).ClearData();
- }
- }
-
- IsQ2PreCorrectionCalculated = false;
- CalculatedQ2PreCorrectionLR = 0;
- CalculatedQ2PreCorrectionRL = 0;
- RawTestInfos = null;
- CompleteTestInfos = null;
- }
-
-
- ///
- /// Main sequence
- ///
- ///
- ///
public void Execute()
{
IList e = new List();
@@ -446,10 +185,17 @@ namespace TBF.BenchControl.Sequences
: ((selection == Selection.Q2) ? "Q2"
: ((selection == Selection.Q3) ? "Q3" : Bridge.SelectedTestName));
+ ///
+ /// Auto invocation actions
+ ///
+ IList procedureBefore = new List();
+ IList testsInside = new List();
+ IList procedureAfer = new List();
///
/// Collect information about the interrupted procedure (if applicable)
///
+ bool restoreInterruptedSession = false;
bool processDataHeaderOK = false;
string interruptedProcedureName = string.Empty;
bool isRemoteIntProc = false;
@@ -477,6 +223,8 @@ namespace TBF.BenchControl.Sequences
UiBridge.Bridge.OnError(this, Strings.Invalid_batch_number);
continue;
}
+
+ restoreInterruptedSession = true;
}
@@ -490,8 +238,10 @@ namespace TBF.BenchControl.Sequences
///
/// Try to load all parameters of selected or restored procedure from the respective database
///
- if (processDataHeaderOK)
+ if (restoreInterruptedSession)
{
+ /// User has chosen to restore an interrupted session and necessary conditions are met
+
/// TODO: Repeate twice for Users.Entities.DBKind.Config and Users.Entities.DBKind.RemoteConfig
using (ISession remoteOrLocalSession = Config.FluentCommon.CreateSession(isRemoteIntProc ?
Users.Entities.DBKind.RemoteConfig :
@@ -500,22 +250,37 @@ namespace TBF.BenchControl.Sequences
StateMachine.LoadProcedure(remoteOrLocalSession, interruptedProcedureName, isRemoteIntProc);
StateMachine.LoadProcedureParams(StateMachine.Procedure);
- /// This is to load Procedure.Tests and tets.MoreParams for each test
+ /// This is to load Procedure.Tests and test.MoreParams for each test
int a = 0;
foreach (var test in StateMachine.Procedure.Tests) a += test.MoreParams.Count;
}
}
else if ((Bridge.SelectedProcedure != null) && !string.IsNullOrEmpty(Bridge.SelectedProcedure.Name))
{
+ if (selection == Selection.Cycle)
+ {
+ /// This is a regular complete cycle => check AutoAction==InvokeXY calendar events
+ procedureBefore = ServeCalendarEventsInvokeXY(Config.CalendarEvent.AutoAction.InvokeBeforeCycle, 1);
+
+ if (procedureBefore.Count == 1)
+ {
+ /// TODO: Invoke procedure before a cycle
+ }
+ else
+ {
+ testsInside = ServeCalendarEventsInvokeXY(Config.CalendarEvent.AutoAction.InvokeInsideCycle);
+ }
+ }
+
/// TODO: Repeate twice for Users.Entities.DBKind.Config and Users.Entities.DBKind.RemoteConfig
using (ISession remoteOrLocalSession = Config.FluentCommon.CreateSession(Bridge.SelectedProcedure.IsRemote ?
Users.Entities.DBKind.RemoteConfig :
Users.Entities.DBKind.Config))
{
- StateMachine.LoadProcedure(remoteOrLocalSession, Bridge.SelectedProcedure.Name, Bridge.SelectedProcedure.IsRemote);
+ StateMachine.LoadProcedure(remoteOrLocalSession, Bridge.SelectedProcedure.Name, Bridge.SelectedProcedure.IsRemote, testsInside);
StateMachine.LoadProcedureParams(StateMachine.Procedure);
- /// This is to load Procedure.Tests and tets.MoreParams for each test
+ /// This is to load Procedure.Tests and test.MoreParams for each test
int a = 0;
foreach (var test in StateMachine.Procedure.Tests) a += test.MoreParams.Count;
}
@@ -1651,565 +1416,5 @@ namespace TBF.BenchControl.Sequences
Shutdown,
RestoreInterruptedSession,
}
-
-
- ///
- /// Idle loop to make a procedure or test selection.
- /// Handles tank emptying, camera test.
- ///
- /// Context where MakeSelection() is called
- ///
- /// Selection.PurgeBegin, PurgeEnd, Break, Cycle, Test, Q1, Q2, Q3 or SaveResults
- ///
- Selection MakeSelection(MKSelContext context)
- {
- log.WarnFormat("MakeSelection({0})", context);
-
- bool restoreIntrptdSessionEnabled = (context == MKSelContext.ProcedureNotSelected) && File.Exists(ProcessData.PDataFileName);
-
- /// Tank emptying valves states
- bool draining1 = false;
- bool draining2 = false;
- bool draining3 = false;
-
- /// Measured masses to control emptying
- DoubleBox mass1 = new DoubleBox();
- DoubleBox mass2 = new DoubleBox();
- DoubleBox mass3 = new DoubleBox();
-
- IList e;
-
- while (true)
- {
- bool draining = draining1 || draining2 || draining3;
-
- ///
- /// Activity message
- ///
- Bridge.OnActivity(this, draining ? Strings.Emptying_tank
- : ((context == MKSelContext.ProcedureNotSelected) ? Strings.Please_select_a_procedure
- : Strings.Please_select_a_cycle_a_test_or_empty));
-
- bool saveResultsActive = (context == MKSelContext.InsideProcedure)
- && (StateMachine.Procedure != null)
- && (!StateMachine.Procedure.MustBeComplete || BatchRslts.AllTestsDone());
-
- /// Enable appropriate UI controls and buttons
- Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
- ButtonsEtc.TestCmbBoxEn |
- ((context == MKSelContext.InsideProcedure) ? ButtonsEtc.Break : 0) |
- (restoreIntrptdSessionEnabled ? ButtonsEtc.RestoreSession : 0) |
- (saveResultsActive ? ButtonsEtc.AcceptResultsBtnEn : 0) |
- (draining ? 0 : ButtonsEtc.StartCycleBtnEn) |
- (draining ? 0 : ButtonsEtc.StartTestBtnsEn) |
- (draining ? 0 : ButtonsEtc.PurgeBeginBtnEn) |
- (draining ? 0 : ((context == MKSelContext.InsideProcedure) ? ButtonsEtc.PurgeEndBtnEn : 0)) |
- ((StateMachine.DrainValve1 == null) ? 0 : (draining1 ? ButtonsEtc.DrainTankBtn1Hi : ButtonsEtc.DrainTankBtn1En)) |
- ((StateMachine.DrainValve2 == null) ? 0 : (draining2 ? ButtonsEtc.DrainTankBtn2Hi : ButtonsEtc.DrainTankBtn2En)) |
- ((StateMachine.DrainValve3 == null) ? 0 : (draining3 ? ButtonsEtc.DrainTankBtn3Hi : ButtonsEtc.DrainTankBtn3En)));
-
-
- State.Create("MainSeq : Select an activity")
- .AddOperation(checkUiOp)
- .AddOperation(StateMachine.BenchWaitingOp)
- .AddOperation((StateMachine.Tank1 is IScale) ? (StateMachine.Tank1 as IScale).ReadMassOp(ref mass1) : null)
- .AddOperation((StateMachine.Tank2 is IScale) ? (StateMachine.Tank2 as IScale).ReadMassOp(ref mass2) : null)
- .AddOperation((StateMachine.Tank3 is IScale) ? (StateMachine.Tank3 as IScale).ReadMassOp(ref mass3) : null)
- .EnterState();
- do
- {
- e = StateMachine.WaitRunDevsRunOps();
-
- /// Handled inside MakeSelection() inside the selection loop
- if (e.Contains(Event.Error)) break;
- if (!draining1 && e.Contains(Event.UiCmdDrainTank1)) break;
- if (!draining2 && e.Contains(Event.UiCmdDrainTank2)) break;
- if (!draining3 && e.Contains(Event.UiCmdDrainTank3)) break;
- if (draining1 && e.Contains(Event.UiCmdStopDrainingTank1)) break;
- if (draining2 && e.Contains(Event.UiCmdStopDrainingTank2)) break;
- if (draining3 && e.Contains(Event.UiCmdStopDrainingTank3)) break;
- if (draining1 && StateMachine.Tank1.IsEmpty()) break;
- if (draining2 && StateMachine.Tank2.IsEmpty()) break;
- if (draining3 && StateMachine.Tank3.IsEmpty()) break;
-
- /// Quit the selection loop and leave MakeSelection()
- if (e.Contains(Event.UiCmdShutdown)) return Selection.Shutdown;
- if (context == MKSelContext.InsideProcedure
- && e.Contains(Event.UiCmdBreak)) return Selection.Break;
- if (e.Contains(Event.UiCmdPurgeBegin)) return Selection.PurgeBegin;
- if (e.Contains(Event.UiCmdPurgeEnd)) return Selection.PurgeEnd;
- if (e.Contains(Event.UiCmdStartCycle)) return Selection.Cycle;
- if (e.Contains(Event.UiCmdStartTest)) return Selection.Test;
- if (e.Contains(Event.UiCmdStartQ1)) return Selection.Q1;
- if (e.Contains(Event.UiCmdStartQ2)) return Selection.Q2;
- if (e.Contains(Event.UiCmdStartQ3)) return Selection.Q3;
- if (e.Contains(Event.UiCmdAcceptResults)) return Selection.SaveResults;
- if (e.Contains(Event.UiCmdReloadBatch)) return Selection.RestoreBatch;
- if (e.Contains(Event.UiCmdReloadAndFixBatch)) return Selection.RestoreAndFixBatch;
- if (restoreIntrptdSessionEnabled
- && e.Contains(Event.UiCmdRestoreSession)) return Selection.RestoreInterruptedSession;
- }
- while (true);
-
-
- if (e.Contains(Event.Error))
- {
- ///------------------------------------
- Bridge.OnActivity(this, Strings.Error);
- ///------------------------------------
- State.Create("MainSeq : ERROR state")
- .AddOperation(checkUiOp)
- .AddOperation(StateMachine.BenchErrorOp)
- .EnterState();
- do
- {
- e = StateMachine.WaitRunDevsRunOps();
- }
- while (!e.Contains(Event.UiCmdShutdown));
-
- return Selection.Shutdown;
- }
- else
- {
- string stateText = "MainSeq : ";
- IList openValves = new List();
- IList closeValves = new List();
-
- if (draining1 && (StateMachine.Tank1.IsEmpty() || e.Contains(Event.UiCmdStopDrainingTank1)))
- {
- draining1 = false;
- closeValves.Add(StateMachine.DrainValve1);
- stateText = stateText + "close tank 1, ";
- }
- else if (draining2 && (StateMachine.Tank2.IsEmpty() || e.Contains(Event.UiCmdStopDrainingTank2)))
- {
- draining2 = false;
- closeValves.Add(StateMachine.DrainValve2);
- stateText = stateText + "close tank 2, ";
- }
- else if (draining3 && (StateMachine.Tank3.IsEmpty() || e.Contains(Event.UiCmdStopDrainingTank3)))
- {
- draining3 = false;
- closeValves.Add(StateMachine.DrainValve3);
- stateText = stateText + "close tank 3, ";
- }
- else if (!draining1 && e.Contains(Event.UiCmdDrainTank1))
- {
- draining1 = true;
- openValves.Add(StateMachine.DrainValve1);
- stateText = stateText + "open tank 1, ";
- }
- else if (!draining2 && e.Contains(Event.UiCmdDrainTank2))
- {
- draining2 = true;
- openValves.Add(StateMachine.DrainValve2);
- stateText = stateText + "open tank 2, ";
- }
- else if (!draining3 && e.Contains(Event.UiCmdDrainTank3))
- {
- draining3 = true;
- openValves.Add(StateMachine.DrainValve3);
- stateText = stateText + "open tank 3, ";
- }
-
- draining = draining1 || draining2 || draining3;
- if (draining) Bridge.OnActivity(this, Strings.Emptying_tank);
-
- Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
- ((StateMachine.DrainValve1 == null) ? 0 : (draining1 ? ButtonsEtc.DrainTankBtn1Hi : ButtonsEtc.DrainTankBtn1En)) |
- ((StateMachine.DrainValve2 == null) ? 0 : (draining2 ? ButtonsEtc.DrainTankBtn2Hi : ButtonsEtc.DrainTankBtn2En)) |
- ((StateMachine.DrainValve3 == null) ? 0 : (draining3 ? ButtonsEtc.DrainTankBtn3Hi : ButtonsEtc.DrainTankBtn3En)));
-
- State.Create(stateText)
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(openValves, closeValves))
- .EnterState();
- do
- {
- e = StateMachine.WaitRunDevsRunOps();
- }
- while (e.Contains(Event.ValvesBusy));
- }
- }
- }
-
- void Shutdown(bool skipTankDraining = false)
- {
- log.WarnFormat(string.Format("Shutdown(skipTankDraining={0})", skipTankDraining));
-
- StateMachine.MachineState = MachineState.ShuttingDown; /// TBF shut down cannot be aborted from now on
- Bridge.Bench2UI(0); /// All buttons off
-
- if (!skipTankDraining)
- {
- /// Drain time
- int maxDrainTime = 0;
- if ((StateMachine.Tank1 != null) && (StateMachine.Tank1.EmptyTimeSec > maxDrainTime)) maxDrainTime = StateMachine.Tank1.EmptyTimeSec;
- if ((StateMachine.Tank2 != null) && (StateMachine.Tank2.EmptyTimeSec > maxDrainTime)) maxDrainTime = StateMachine.Tank2.EmptyTimeSec;
- if ((StateMachine.Tank3 != null) && (StateMachine.Tank3.EmptyTimeSec > maxDrainTime)) maxDrainTime = StateMachine.Tank3.EmptyTimeSec;
-
- /// Drain valves
- IList drainValves = new List();
- if (StateMachine.DrainValve1 != null) drainValves.Add(StateMachine.DrainValve1);
- if (StateMachine.DrainValve2 != null) drainValves.Add(StateMachine.DrainValve2);
- if (StateMachine.DrainValve3 != null) drainValves.Add(StateMachine.DrainValve3);
-
- /// Open all drain valves
- if (drainValves.Count > 0)
- {
- Bridge.OnActivity(this, Strings.Emptying_tank); /// Activity message
-
- State.Create("Open all drain valves")
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(drainValves, null))
- .EnterState();
- while (StateMachine.WaitRunDevsRunOps().Contains(Event.ValvesBusy)) { }
- }
-
- /// Tank emptying valves states
- bool draining1 = (StateMachine.DrainValve1 != null);
- bool draining2 = (StateMachine.DrainValve2 != null);
- bool draining3 = (StateMachine.DrainValve3 != null);
-
- int drainingStartTime = StateMachine.Time;
-
- /// Quit the following loop when time expires or all tanks are empty
- while ((StateMachine.Time < drainingStartTime + maxDrainTime) && (draining1 || draining2 || draining3))
- {
- int remTime = drainingStartTime + maxDrainTime - StateMachine.Time;
- Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remTime / 60, "min", remTime % 60, Strings.sec));
-
- DoubleBox mass1 = new DoubleBox();
- DoubleBox mass2 = new DoubleBox();
- DoubleBox mass3 = new DoubleBox();
- ///
- State.Create("MainSeq : Reading mass")
- .AddOperation(checkUiOp)
- .AddOperation((StateMachine.Tank1 is IScale) ? (StateMachine.Tank1 as IScale).ReadMassOp(ref mass1) : null)
- .AddOperation((StateMachine.Tank2 is IScale) ? (StateMachine.Tank2 as IScale).ReadMassOp(ref mass2) : null)
- .AddOperation((StateMachine.Tank3 is IScale) ? (StateMachine.Tank3 as IScale).ReadMassOp(ref mass3) : null)
- .EnterState();
- while (StateMachine.WaitRunDevsRunOps().Contains(Event.Busy)) { }
-
- if (draining1 && StateMachine.Tank1.IsEmpty()) draining1 = false;
- if (draining2 && StateMachine.Tank2.IsEmpty()) draining2 = false;
- if (draining3 && StateMachine.Tank3.IsEmpty()) draining3 = false;
- }
-
- /// Close all drain valves
- if (drainValves.Count > 0)
- {
- State.Create("Close all drain valves")
- .AddOperation(StateMachine.ControlBoard.SetValvesOp(null, drainValves))
- .EnterState();
- while (StateMachine.WaitRunDevsRunOps().Contains(Event.ValvesBusy)) { }
- }
- }
-
- ///
- /// Shut down the state machine
- ///
- Bridge.OnActivity(this, Strings.Shutting_down_devices); /// Activity message
-
- State.Create("No operations").EnterState(); /// Stop all operations
- StateMachine.WaitRunDevsRunOps(true);
-
- BenchControl.StateMachine.StopDevices(); /// Stop all devices - phase 1
- Thread.Sleep(100);
- BenchControl.StateMachine.StopDevices2(); /// Stop all devices - phase 2
- }
-
- ///
- /// Create a new empty batch results from the procedure
- ///
- /// New batch number
- /// Selected procedure
- /// Created BatchResults
- Results.BatchResults CreateNewBatchResults(int newBatchNr, Procedure procedure)
- {
- ///
- /// Prepare new water meters
- ///
- foreach (var wm in WaterMeters) wm.ClearData(); /// Clean water meter data
-
- bool compound = (StateMachine.Procedure.MetersKind == MetersKind.Combined);
- bool heatMeters = (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter);
- int waterMetersCount = Math.Min(WaterMeters.Count, heatMeters ? Config.Data.HeatMetersCount : (compound ? Config.Data.CompoundWMsCount : Config.Data.WMsCount));
- ///
- Results.Entities.WaterMeterData[] waterMeterData = new Results.Entities.WaterMeterData[waterMetersCount];
- ///
- int[] waterMeterParts = new int[waterMetersCount];
- for (int wmNr = 0; wmNr < waterMetersCount; wmNr++)
- {
- /// WR10 .. WR15 configuration specific code (iPerl head component name)
- TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead.IperlHead iHead =
- TbfComponents.FindComponent(string.Format("iPerl{0}", wmNr + 1)) as TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead.IperlHead;
-
- int ix = compound ? (2 * wmNr) : wmNr;
- if (WaterMeters.Count > ix)
- {
- waterMeterParts[wmNr] = Utils.PartNr(wmNr + 1, compound);
- waterMeterData[wmNr] = new Results.Entities.WaterMeterData()
- {
- ProductName = WaterMeters[ix].ProductName,
- Producer = WaterMeters[ix].Producer,
-
- L = WaterMeters[ix].L,
- DN = WaterMeters[ix].DN,
- Mounting = WaterMeters[ix].Mounting,
-
- NewQnames = WaterMeters[ix].NewQnames,
- Q4_Qmax = WaterMeters[ix].Q4_Qmax,
- Q3_Qn = WaterMeters[ix].Q3_Qn,
- Q2_Qt = WaterMeters[ix].Q2_Qt,
- Q1_Qmin = WaterMeters[ix].Q1_Qmin,
-
- MetrologicalClass = WaterMeters[ix].MetrologicalClass,
- TemperatureClass = WaterMeters[ix].TemperatureClass,
- PressureLossClass = WaterMeters[ix].PressureLossClass,
- MaxAdmissiblePressure = WaterMeters[ix].MaxAdmissiblePressure,
- FlowProfileSensitivityClass = WaterMeters[ix].FlowProfileSensitivityClass,
-
- ApprovalInfo = WaterMeters[ix].ApprovalInfo,
- Certificate = WaterMeters[ix].Certificate,
-
- PulsesPerLtr = WaterMeters[ix].PulsesPerLtr,
- Medium = WaterMeters[ix].Medium,
- Text1 = WaterMeters[ix].Text1,
- Text2 = WaterMeters[ix].Text2,
- Text3 = WaterMeters[ix].Text3,
- Text4 = WaterMeters[ix].Text4,
- Text5 = WaterMeters[ix].Text5,
-
- Compound = compound,
- HeatMeter = heatMeters,
-#if ORACLE_DB
- WMTypeId = (iHead != null) ? iHead.WMType_ID : 0,
-#endif
- };
- }
-
- int auxIx = 2 * wmNr + 1;
- if (compound && WaterMeters.Count > auxIx)
- {
- waterMeterData[wmNr].ProducerAux = WaterMeters[auxIx].Producer;
- waterMeterData[wmNr].Q3_Qn_Aux = WaterMeters[auxIx].Q3_Qn;
- waterMeterData[wmNr].MetrologicalClassAux = WaterMeters[auxIx].MetrologicalClass;
- waterMeterData[wmNr].ApprovalInfoAux = WaterMeters[auxIx].ApprovalInfo;
- }
- }
-
- /// Prepare empty results
- return Results.BatchResults.NewFromProcedure(newBatchNr,
- (BenchInfo != null) ? BenchInfo.TestBenchId : 1,
- (BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
- (BenchInfo != null) ? BenchInfo.Address1 : string.Empty,
- (BenchInfo != null) ? BenchInfo.Address2 : string.Empty,
- (BenchInfo != null) ? BenchInfo.Address3 : string.Empty,
- (BenchInfo != null) ? BenchInfo.Address4 : string.Empty,
- (BenchInfo != null) ? BenchInfo.Address5 : string.Empty,
- Users.GlobalData.CurrentUser.ToEncodedStr(),
- Users.GlobalData.CurrentUser.Number,
- Program.Version,
- StateMachine.Procedure,
- waterMeterData,
- waterMeterParts,
- Formulas.DensityCorrection(Config.Formulas.RealDensity(),
- Config.Formulas.AtTemperature()));
- }
-
-
- ///
- /// Reload batch results from Results database given the batch number
- ///
- /// Original batch number
- /// New unique batch number
- /// Reloaded procedure
- ///
- void RestoreBatchResults(int oriBatchNr, ref Results.BatchResults batchResults)
- {
- Batch oriBatch = Results.DB.LoadBatch(oriBatchNr);
-
- if (oriBatch == null) return;
-
- batchResults.Batch.StartTime = oriBatch.StartTime;
- batchResults.Batch.TestBenchId = (BenchInfo != null) ? BenchInfo.TestBenchId : 1;
- batchResults.Batch.TestBenchName = (BenchInfo != null) ? BenchInfo.TestBenchName : "testbench";
-
- foreach (var testRslt in batchResults.Batch.TestRslts)
- {
- foreach (var oriTstRslt in oriBatch.TestRslts)
- {
- if (testRslt.Name() == oriTstRslt.Name() &&
- testRslt.Part == oriTstRslt.Part &&
- testRslt.RepetitionNr == oriTstRslt.RepetitionNr)
- {
- testRslt.CopyContentFrom(oriTstRslt);
- break;
- }
- }
- }
-
- for (int i = 0; i < batchResults.Batch.WaterMeters.Count; i++)
- {
- WaterMeter wm = batchResults.Batch.WaterMeters[i];
- wm.Disabled = true;
- foreach (var wm2 in oriBatch.WaterMeters)
- {
- if (wm.WMPosition == wm2.WMPosition)
- {
- wm.CopyContentFrom(wm2);
- wm.Disabled = false;
-#if ORACLE_DB
- wm.WaterMeterData.WMTypeId = wm2.WaterMeterData.WMTypeId;
-#endif
- break;
- }
- }
- }
- }
-
-
- void CollectSimultSteps()
- {
- ///
- /// Collect steps (e.g. iPerl communication) to be done simultaneously with purging
- ///
- simultWithPurgingCount = 0;
- simultWithPurgingCfg = null;
- simultWithPurgingTests.Clear();
- simultWithPurgingParams.Clear();
- ///
- foreach (var test in StateMachine.Tests)
- {
- Generic.IComponent testMethodComp = TbfComponents.FindComponent(test.Method);
- if (testMethodComp == null) break;
-
- testMethodComp.Cfg.LoadTestParamsFromDB(test);
-
- ISimultTestMethod simultTest = testMethodComp as ISimultTestMethod;
- MetersPath sensPath = StateMachine.GetMetersPath(test);
-
- if (simultTest == null || !simultTest.SimultWithPrevious || sensPath == null) break;
-
- if (simultWithPurgingCount == 0)
- {
- simultWithPurgingCfg = simultTest.Cfg;
- }
- else if (simultTest.Cfg != simultWithPurgingCfg)
- {
- break;
- }
-
- simultWithPurgingTests.Add(test);
- simultWithPurgingParams.Add(testMethodComp.Cfg.GetRuntimeTestParamsProvider().Clone() as Generic.ITestParams);
- simultWithPurgingCount++;
- }
-
- ///
- /// Collect steps (e.g. iPerl communication) to be done simultaneously with evacuation
- ///
- simultWithEvacuationCount = 0;
- simultWithEvacuationCfg = null;
- simultWithEvacuationTests.Clear();
- simultWithEvacuationParams.Clear();
- ///
- for (int i = StateMachine.Tests.Count - 1; i >= simultWithPurgingCount; i--)
- {
- var test = StateMachine.Tests[i];
-
- Generic.IComponent testMethodComp = TbfComponents.FindComponent(test.Method);
- if (testMethodComp == null) break;
-
- testMethodComp.Cfg.LoadTestParamsFromDB(test);
-
- ISimultTestMethod simultTest = testMethodComp as ISimultTestMethod;
- MetersPath sensPath = StateMachine.GetMetersPath(test);
-
- if (simultTest == null || !simultTest.SimultWithNext || sensPath == null) break;
-
- if (simultWithEvacuationCount == 0)
- {
- simultWithEvacuationCfg = simultTest.Cfg;
- }
- else if (simultTest.Cfg != simultWithEvacuationCfg)
- {
- break;
- }
-
- simultWithEvacuationTests.Insert(0, test);
- simultWithEvacuationParams.Insert(0, testMethodComp.Cfg.GetRuntimeTestParamsProvider().Clone() as Generic.ITestParams);
- simultWithEvacuationCount++;
- }
- }
-
-
- ///
- /// Executes steps of a evacuation sequence
- ///
- ///
- /// Event.Done Transition sequence completed OK
- /// Event.UiCmdStop Transition sequence interrupted by the STOP on-screen button
- /// Event.Error Error (e.g. RegulValveTimeOut returned by Run() of SetRegulValvePositionOp)
- ///
- Event DoEvacuation(TransitionSequence purgeEnd)
- {
- IList e;
-
- if (simultWithEvacuationCount > 0)
- {
- /// Open iPerlCommunicationForm
- ProcessData.RegisterReaders = StateMachine.GetMetersPath(simultWithEvacuationTests[0]).RegisterReaders;
- Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, simultWithEvacuationCfg, simultWithEvacuationTests, simultWithEvacuationParams });
- }
-
- //--------------------------------------------------------
- benchFilled = false; /// because evacuation sequence started
- ///
- switch (Transition(purgeEnd, TransitionContext.PurgeEnd))
- {
- case Event.Error:
- if (simultWithEvacuationCount > 0) CloseIPerlCommForm();
- return Event.Error;
-
- case Event.UiCmdStop:
- if (simultWithEvacuationCount > 0) CloseIPerlCommForm();
- return Event.UiCmdStop;
-
- default:
- break;
- }
-
- if (simultWithEvacuationCount > 0)
- {
- ///
- /// Wait until iPerl communications are completed
- ///
- bool completed = !(modelessDlg is GenericDevices.IHasCompleted)
- || (modelessDlg as GenericDevices.IHasCompleted).Completed;
- if (!completed)
- {
- State.Create("MainSeq : Wait until the entry form is closed")
- .AddOperation(checkUiOp)
- .EnterState();
- do
- {
- e = StateMachine.WaitRunDevsRunOps();
- if (e.Contains(Event.UiCmdStop))
- {
- CloseIPerlCommForm();
- return Event.UiCmdStop;
- }
-
- completed = (modelessDlg as GenericDevices.IHasCompleted).Completed;
- }
- while (!completed);
- }
-
- modelessDlg = null;
- }
-
- Bridge.Bench2UI(ButtonsEtc.ShowBenchEmpty);
-
- return Event.Done;
- }
}
}
diff --git a/TBF/BenchControl/Sequences/MainSeqUtils.cs b/TBF/BenchControl/Sequences/MainSeqUtils.cs
new file mode 100644
index 000000000..b7ee7cfcd
--- /dev/null
+++ b/TBF/BenchControl/Sequences/MainSeqUtils.cs
@@ -0,0 +1,840 @@
+///
+/// Copyright (c) 2020 Sensus Slovensko a.s.
+///
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using Config.Entities;
+using TBF.BenchControl.GenericDevices;
+using TBF.BenchControl.Operations;
+using TBF.Boxes;
+using TBF.Resources;
+using TBF.UiBridge;
+using Results.Entities;
+
+namespace TBF.BenchControl.Sequences
+{
+ partial class MainSeq
+ {
+ ///
+ /// Wrapper
+ ///
+ IList ServeCalendarEventsInvokeXY(Config.CalendarEvent.AutoAction selectedAction, int maxCount = 1)
+ {
+ return TBF.UI.Calendar.CalendarTabPageCtrl.ServeCalendarEventsInvokeXY(selectedAction, maxCount);
+ }
+
+ ///
+ /// Unconditionally wait for OK button
+ ///
+ void WaitForOkButton()
+ {
+ State.Create("MainSeq : Press OK to start the system")
+ .AddOperation(new BenchControl.Operations.MessageBoxOp(Strings.Start_the_test_bench, System.Drawing.Color.OliveDrab))
+ .EnterState();
+
+ while (!StateMachine.WaitRunDevsRunOps().Contains(Event.OK)) { }
+ }
+
+ ///
+ /// Unconditionally set valves to default position
+ ///
+ void SetValvesToDefaultState()
+ {
+ State.Create("MainSeq : Setting valves to default positions")
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose))
+ .EnterState();
+
+ while (StateMachine.WaitRunDevsRunOps().Contains(Event.ValvesBusy)) { }
+ }
+
+ ///
+ /// Test communication with all scales that support S/N read operation
+ ///
+ /// Name of a scale that failed
+ /// Message in case of a failure
+ /// true = Test passed, all scales communicate OK
+ bool TestCommunicationWithScales(out string scaleName, out string message)
+ {
+ ///
+ /// Read S/N-s from scales (cannot be stopped, but is limitted to Scales count x 3s (=timeout)
+ ///
+ IScaleOrTank[] tanks = new IScaleOrTank[] { StateMachine.Tank1, StateMachine.Tank2, StateMachine.Tank3 };
+
+ foreach (var tank in tanks)
+ {
+ if (tank is IScale)
+ {
+ IScale scale = tank as IScale;
+ string sn = string.Empty;
+ IOperation getSNOp = scale.GetSerNumOp(ref sn);
+
+ if (getSNOp != null)
+ {
+ const int nrRetries = 3;
+
+ for (int i = 1; i <= nrRetries; i++)
+ {
+ IList e;
+ bool error = false;
+ bool timeout = false;
+
+ State.Create(string.Format("MainSeq : Reading S/N of scale {0} trial {1}", scale.Name, i))
+ .AddOperation(getSNOp)
+ .AddOperation(new Operations.TimerOp(2))
+ .EnterState();
+ do
+ {
+ e = StateMachine.WaitRunDevsRunOps();
+ if (e.Contains(Event.Error))
+ {
+ if (i == nrRetries)
+ {
+ ///
+ /// All retries completed => the scale failed
+ ///
+ scaleName = scale.Name;
+ message = Strings.Scale_communication_error;
+ return false;
+ }
+ else
+ {
+ /// The scale failed => try one more time
+ error = true;
+ break;
+ }
+ }
+ if (e.Contains(Event.Busy) && e.Contains(Event.TimerExpired))
+ {
+ if (i == nrRetries)
+ {
+ ///
+ /// All retries completed, the scale failed
+ ///
+ scaleName = scale.Name;
+ message = Strings.Scale_communication_timeout;
+ return false;
+ }
+ else
+ {
+ /// The scale failed => try one more time
+ timeout = true;
+ break;
+ }
+ }
+ }
+ while (e.Contains(Event.Busy));
+
+ if (!error && !timeout)
+ {
+ /// This scale communicates OK, break "for (int i = ... " loop
+ if (!string.IsNullOrEmpty(sn)) log.WarnFormat("Scale {0} : s/n = {1}", scale.Name, sn);
+ break; ///
+ }
+
+ /// Wait one state machine tick (1 second), kreep retrying, stay inside "for (int i = ... " loop
+ State.Create(string.Format("MainSeq : Reading S/N of scale {0}", scale.Name)).EnterState();
+ StateMachine.WaitRunDevsRunOps();
+ }
+ }
+ }
+ }
+
+ ///
+ /// All scales communicate OK, test passed
+ ///
+ scaleName = string.Empty;
+ message = string.Empty;
+ return true;
+ }
+
+ ///
+ ///
+ ///
+ /// true = OK, false = error
+ bool DrainTanks()
+ {
+ IList e;
+
+ ///
+ /// Enable stop draining buttons
+ ///
+ Bridge.Bench2UI(((StateMachine.DrainValve1 != null) ? ButtonsEtc.DrainTankBtn1Hi : 0) |
+ ((StateMachine.DrainValve2 != null) ? ButtonsEtc.DrainTankBtn2Hi : 0) |
+ ((StateMachine.DrainValve3 != null) ? ButtonsEtc.DrainTankBtn3Hi : 0));
+
+ ///
+ /// Determine lists of drain valves and drain times (max. of all tank drain times)
+ ///
+ IList fullDrainValves = new List();
+ IList secondHalfDrainValves = new List();
+ IList allDrainValves = new List();
+ int totalDrainTime = 0;
+ int maxDrainTimeFor2VlvTanks = 0;
+ bool areTwoDrainPhases = false;
+ foreach (IScaleOrTank tank in new IScaleOrTank[] { StateMachine.Tank1, StateMachine.Tank2, StateMachine.Tank3 })
+ {
+ if (tank != null && tank.DrainValve != null)
+ {
+ if (tank.EmptyTimeSec > totalDrainTime) totalDrainTime = tank.EmptyTimeSec;
+ if (tank.DrainValve2 != null)
+ {
+ areTwoDrainPhases = true;
+ if (tank.EmptyTimeSec > maxDrainTimeFor2VlvTanks) maxDrainTimeFor2VlvTanks = tank.EmptyTimeSec;
+
+ if (!secondHalfDrainValves.Contains(tank.DrainValve)) secondHalfDrainValves.Add(tank.DrainValve);
+ if (!fullDrainValves.Contains(tank.DrainValve2)) fullDrainValves.Add(tank.DrainValve2);
+ if (!allDrainValves.Contains(tank.DrainValve)) allDrainValves.Add(tank.DrainValve);
+ if (!allDrainValves.Contains(tank.DrainValve2)) allDrainValves.Add(tank.DrainValve2);
+ }
+ else
+ {
+ if (!fullDrainValves.Contains(tank.DrainValve)) fullDrainValves.Add(tank.DrainValve);
+ if (!allDrainValves.Contains(tank.DrainValve)) allDrainValves.Add(tank.DrainValve);
+ }
+ }
+ }
+
+ ///
+ /// Drain the tanks, two phases if necessary
+ ///
+ if (totalDrainTime > 0)
+ {
+ IntBox timerTime = new IntBox(); /// Contains remaining time in each phase
+ int firstPhaseTime = maxDrainTimeFor2VlvTanks / 2;
+
+ State.Create(areTwoDrainPhases ? "MainSeq : Drain tanks - phase 1" : "MainSeq : Drain tanks")
+ .AddOperation(checkUiOp)
+ .AddOperation(new TimerOp(areTwoDrainPhases ? firstPhaseTime : totalDrainTime, timerTime))
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(fullDrainValves, null))
+ .EnterState();
+ do
+ {
+ int remTime = areTwoDrainPhases ? (timerTime.Val + totalDrainTime - firstPhaseTime) : timerTime.Val;
+ Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remTime / 60, "min", remTime % 60, Strings.sec));
+
+ e = StateMachine.WaitRunDevsRunOps();
+ if (e.Contains(Event.Error)) return false;
+ bool stopDrainingCmd = e.Contains(Event.UiCmdStopDrainingTank1) || e.Contains(Event.UiCmdStopDrainingTank2) || e.Contains(Event.UiCmdStopDrainingTank3);
+ if (stopDrainingCmd && !e.Contains(Event.ValvesBusy) && !e.Contains(Event.CameraBusy)) break;
+ }
+ while (e.Contains(Event.TimerBusy) || e.Contains(Event.CameraBusy) || e.Contains(Event.ValvesBusy));
+
+ if (areTwoDrainPhases)
+ {
+ State.Create("MainSeq : Drain tanks - phase 2")
+ .AddOperation(checkUiOp)
+ .AddOperation(new TimerOp(totalDrainTime - firstPhaseTime, timerTime))
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(secondHalfDrainValves, null))
+ .EnterState();
+ do
+ {
+ int remTime = timerTime.Val;
+ Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remTime / 60, "min", remTime % 60, Strings.sec));
+
+ e = StateMachine.WaitRunDevsRunOps();
+ if (e.Contains(Event.Error)) return false;
+ bool stopDrainingCmd = e.Contains(Event.UiCmdStopDrainingTank1) || e.Contains(Event.UiCmdStopDrainingTank2) || e.Contains(Event.UiCmdStopDrainingTank3);
+ if (stopDrainingCmd && !e.Contains(Event.ValvesBusy) && !e.Contains(Event.CameraBusy)) break;
+ }
+ while (e.Contains(Event.TimerBusy) || e.Contains(Event.CameraBusy) || e.Contains(Event.ValvesBusy));
+ }
+
+ Bridge.OnActivity(this, Strings.Emptying_tank);
+
+ State stopDraining = State.Create("MainSeq : Stop draining water tanks")
+ .AddOperation(checkUiOp)
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(null, allDrainValves))
+ .EnterState();
+ do
+ {
+ e = StateMachine.WaitRunDevsRunOps();
+ if (e.Contains(Event.Error)) return false;
+ }
+ while (e.Contains(Event.ValvesBusy));
+ }
+
+ return true; /// OK
+ }
+
+ ///
+ /// This function is called after a procedure was selected and all components procedure parameters of components were loaded
+ ///
+ void ClearSessionData()
+ {
+ ///
+ /// Clear iperlhead data (including PCB Number, avoid double use)
+ ///
+ foreach (var cmpnt in StateMachine.Components)
+ {
+ if (cmpnt is TestMethods.iPerlCommunication.iPerlHead.IperlHead)
+ {
+ (cmpnt as TestMethods.iPerlCommunication.iPerlHead.IperlHead).ClearData();
+ }
+ }
+
+ IsQ2PreCorrectionCalculated = false;
+ CalculatedQ2PreCorrectionLR = 0;
+ CalculatedQ2PreCorrectionRL = 0;
+ RawTestInfos = null;
+ CompleteTestInfos = null;
+ }
+
+ ///
+ /// Idle loop to make a procedure or test selection.
+ /// Handles tank emptying, camera test.
+ ///
+ /// Context where MakeSelection() is called
+ ///
+ /// Selection.PurgeBegin, PurgeEnd, Break, Cycle, Test, Q1, Q2, Q3 or SaveResults
+ ///
+ Selection MakeSelection(MKSelContext context)
+ {
+ log.WarnFormat("MakeSelection({0})", context);
+
+ bool restoreIntrptdSessionEnabled = (context == MKSelContext.ProcedureNotSelected) && File.Exists(ProcessData.PDataFileName);
+
+ /// Tank emptying valves states
+ bool draining1 = false;
+ bool draining2 = false;
+ bool draining3 = false;
+
+ /// Measured masses to control emptying
+ DoubleBox mass1 = new DoubleBox();
+ DoubleBox mass2 = new DoubleBox();
+ DoubleBox mass3 = new DoubleBox();
+
+ IList e;
+
+ while (true)
+ {
+ bool draining = draining1 || draining2 || draining3;
+
+ ///
+ /// Activity message
+ ///
+ Bridge.OnActivity(this, draining ? Strings.Emptying_tank
+ : ((context == MKSelContext.ProcedureNotSelected) ? Strings.Please_select_a_procedure
+ : Strings.Please_select_a_cycle_a_test_or_empty));
+
+ bool saveResultsActive = (context == MKSelContext.InsideProcedure)
+ && (StateMachine.Procedure != null)
+ && (!StateMachine.Procedure.MustBeComplete || BatchRslts.AllTestsDone());
+
+ /// Enable appropriate UI controls and buttons
+ Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
+ ButtonsEtc.TestCmbBoxEn |
+ ((context == MKSelContext.InsideProcedure) ? ButtonsEtc.Break : 0) |
+ (restoreIntrptdSessionEnabled ? ButtonsEtc.RestoreSession : 0) |
+ (saveResultsActive ? ButtonsEtc.AcceptResultsBtnEn : 0) |
+ (draining ? 0 : ButtonsEtc.StartCycleBtnEn) |
+ (draining ? 0 : ButtonsEtc.StartTestBtnsEn) |
+ (draining ? 0 : ButtonsEtc.PurgeBeginBtnEn) |
+ (draining ? 0 : ((context == MKSelContext.InsideProcedure) ? ButtonsEtc.PurgeEndBtnEn : 0)) |
+ ((StateMachine.DrainValve1 == null) ? 0 : (draining1 ? ButtonsEtc.DrainTankBtn1Hi : ButtonsEtc.DrainTankBtn1En)) |
+ ((StateMachine.DrainValve2 == null) ? 0 : (draining2 ? ButtonsEtc.DrainTankBtn2Hi : ButtonsEtc.DrainTankBtn2En)) |
+ ((StateMachine.DrainValve3 == null) ? 0 : (draining3 ? ButtonsEtc.DrainTankBtn3Hi : ButtonsEtc.DrainTankBtn3En)));
+
+
+ State.Create("MainSeq : Select an activity")
+ .AddOperation(checkUiOp)
+ .AddOperation(StateMachine.BenchWaitingOp)
+ .AddOperation((StateMachine.Tank1 is IScale) ? (StateMachine.Tank1 as IScale).ReadMassOp(ref mass1) : null)
+ .AddOperation((StateMachine.Tank2 is IScale) ? (StateMachine.Tank2 as IScale).ReadMassOp(ref mass2) : null)
+ .AddOperation((StateMachine.Tank3 is IScale) ? (StateMachine.Tank3 as IScale).ReadMassOp(ref mass3) : null)
+ .EnterState();
+ do
+ {
+ e = StateMachine.WaitRunDevsRunOps();
+
+ /// Handled inside MakeSelection() inside the selection loop
+ if (e.Contains(Event.Error)) break;
+ if (!draining1 && e.Contains(Event.UiCmdDrainTank1)) break;
+ if (!draining2 && e.Contains(Event.UiCmdDrainTank2)) break;
+ if (!draining3 && e.Contains(Event.UiCmdDrainTank3)) break;
+ if (draining1 && e.Contains(Event.UiCmdStopDrainingTank1)) break;
+ if (draining2 && e.Contains(Event.UiCmdStopDrainingTank2)) break;
+ if (draining3 && e.Contains(Event.UiCmdStopDrainingTank3)) break;
+ if (draining1 && StateMachine.Tank1.IsEmpty()) break;
+ if (draining2 && StateMachine.Tank2.IsEmpty()) break;
+ if (draining3 && StateMachine.Tank3.IsEmpty()) break;
+
+ /// Quit the selection loop and leave MakeSelection()
+ if (e.Contains(Event.UiCmdShutdown)) return Selection.Shutdown;
+ if (context == MKSelContext.InsideProcedure
+ && e.Contains(Event.UiCmdBreak)) return Selection.Break;
+ if (e.Contains(Event.UiCmdPurgeBegin)) return Selection.PurgeBegin;
+ if (e.Contains(Event.UiCmdPurgeEnd)) return Selection.PurgeEnd;
+ if (e.Contains(Event.UiCmdStartCycle)) return Selection.Cycle;
+ if (e.Contains(Event.UiCmdStartTest)) return Selection.Test;
+ if (e.Contains(Event.UiCmdStartQ1)) return Selection.Q1;
+ if (e.Contains(Event.UiCmdStartQ2)) return Selection.Q2;
+ if (e.Contains(Event.UiCmdStartQ3)) return Selection.Q3;
+ if (e.Contains(Event.UiCmdAcceptResults)) return Selection.SaveResults;
+ if (e.Contains(Event.UiCmdReloadBatch)) return Selection.RestoreBatch;
+ if (e.Contains(Event.UiCmdReloadAndFixBatch)) return Selection.RestoreAndFixBatch;
+ if (restoreIntrptdSessionEnabled
+ && e.Contains(Event.UiCmdRestoreSession)) return Selection.RestoreInterruptedSession;
+ }
+ while (true);
+
+
+ if (e.Contains(Event.Error))
+ {
+ ///------------------------------------
+ Bridge.OnActivity(this, Strings.Error);
+ ///------------------------------------
+ State.Create("MainSeq : ERROR state")
+ .AddOperation(checkUiOp)
+ .AddOperation(StateMachine.BenchErrorOp)
+ .EnterState();
+ do
+ {
+ e = StateMachine.WaitRunDevsRunOps();
+ }
+ while (!e.Contains(Event.UiCmdShutdown));
+
+ return Selection.Shutdown;
+ }
+ else
+ {
+ string stateText = "MainSeq : ";
+ IList openValves = new List();
+ IList closeValves = new List();
+
+ if (draining1 && (StateMachine.Tank1.IsEmpty() || e.Contains(Event.UiCmdStopDrainingTank1)))
+ {
+ draining1 = false;
+ closeValves.Add(StateMachine.DrainValve1);
+ stateText = stateText + "close tank 1, ";
+ }
+ else if (draining2 && (StateMachine.Tank2.IsEmpty() || e.Contains(Event.UiCmdStopDrainingTank2)))
+ {
+ draining2 = false;
+ closeValves.Add(StateMachine.DrainValve2);
+ stateText = stateText + "close tank 2, ";
+ }
+ else if (draining3 && (StateMachine.Tank3.IsEmpty() || e.Contains(Event.UiCmdStopDrainingTank3)))
+ {
+ draining3 = false;
+ closeValves.Add(StateMachine.DrainValve3);
+ stateText = stateText + "close tank 3, ";
+ }
+ else if (!draining1 && e.Contains(Event.UiCmdDrainTank1))
+ {
+ draining1 = true;
+ openValves.Add(StateMachine.DrainValve1);
+ stateText = stateText + "open tank 1, ";
+ }
+ else if (!draining2 && e.Contains(Event.UiCmdDrainTank2))
+ {
+ draining2 = true;
+ openValves.Add(StateMachine.DrainValve2);
+ stateText = stateText + "open tank 2, ";
+ }
+ else if (!draining3 && e.Contains(Event.UiCmdDrainTank3))
+ {
+ draining3 = true;
+ openValves.Add(StateMachine.DrainValve3);
+ stateText = stateText + "open tank 3, ";
+ }
+
+ draining = draining1 || draining2 || draining3;
+ if (draining) Bridge.OnActivity(this, Strings.Emptying_tank);
+
+ Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
+ ((StateMachine.DrainValve1 == null) ? 0 : (draining1 ? ButtonsEtc.DrainTankBtn1Hi : ButtonsEtc.DrainTankBtn1En)) |
+ ((StateMachine.DrainValve2 == null) ? 0 : (draining2 ? ButtonsEtc.DrainTankBtn2Hi : ButtonsEtc.DrainTankBtn2En)) |
+ ((StateMachine.DrainValve3 == null) ? 0 : (draining3 ? ButtonsEtc.DrainTankBtn3Hi : ButtonsEtc.DrainTankBtn3En)));
+
+ State.Create(stateText)
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(openValves, closeValves))
+ .EnterState();
+ do
+ {
+ e = StateMachine.WaitRunDevsRunOps();
+ }
+ while (e.Contains(Event.ValvesBusy));
+ }
+ }
+ }
+
+ void Shutdown(bool skipTankDraining = false)
+ {
+ log.WarnFormat(string.Format("Shutdown(skipTankDraining={0})", skipTankDraining));
+
+ StateMachine.MachineState = MachineState.ShuttingDown; /// TBF shut down cannot be aborted from now on
+ Bridge.Bench2UI(0); /// All buttons off
+
+ if (!skipTankDraining)
+ {
+ /// Drain time
+ int maxDrainTime = 0;
+ if ((StateMachine.Tank1 != null) && (StateMachine.Tank1.EmptyTimeSec > maxDrainTime)) maxDrainTime = StateMachine.Tank1.EmptyTimeSec;
+ if ((StateMachine.Tank2 != null) && (StateMachine.Tank2.EmptyTimeSec > maxDrainTime)) maxDrainTime = StateMachine.Tank2.EmptyTimeSec;
+ if ((StateMachine.Tank3 != null) && (StateMachine.Tank3.EmptyTimeSec > maxDrainTime)) maxDrainTime = StateMachine.Tank3.EmptyTimeSec;
+
+ /// Drain valves
+ IList drainValves = new List();
+ if (StateMachine.DrainValve1 != null) drainValves.Add(StateMachine.DrainValve1);
+ if (StateMachine.DrainValve2 != null) drainValves.Add(StateMachine.DrainValve2);
+ if (StateMachine.DrainValve3 != null) drainValves.Add(StateMachine.DrainValve3);
+
+ /// Open all drain valves
+ if (drainValves.Count > 0)
+ {
+ Bridge.OnActivity(this, Strings.Emptying_tank); /// Activity message
+
+ State.Create("Open all drain valves")
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(drainValves, null))
+ .EnterState();
+ while (StateMachine.WaitRunDevsRunOps().Contains(Event.ValvesBusy)) { }
+ }
+
+ /// Tank emptying valves states
+ bool draining1 = (StateMachine.DrainValve1 != null);
+ bool draining2 = (StateMachine.DrainValve2 != null);
+ bool draining3 = (StateMachine.DrainValve3 != null);
+
+ int drainingStartTime = StateMachine.Time;
+
+ /// Quit the following loop when time expires or all tanks are empty
+ while ((StateMachine.Time < drainingStartTime + maxDrainTime) && (draining1 || draining2 || draining3))
+ {
+ int remTime = drainingStartTime + maxDrainTime - StateMachine.Time;
+ Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remTime / 60, "min", remTime % 60, Strings.sec));
+
+ DoubleBox mass1 = new DoubleBox();
+ DoubleBox mass2 = new DoubleBox();
+ DoubleBox mass3 = new DoubleBox();
+ ///
+ State.Create("MainSeq : Reading mass")
+ .AddOperation(checkUiOp)
+ .AddOperation((StateMachine.Tank1 is IScale) ? (StateMachine.Tank1 as IScale).ReadMassOp(ref mass1) : null)
+ .AddOperation((StateMachine.Tank2 is IScale) ? (StateMachine.Tank2 as IScale).ReadMassOp(ref mass2) : null)
+ .AddOperation((StateMachine.Tank3 is IScale) ? (StateMachine.Tank3 as IScale).ReadMassOp(ref mass3) : null)
+ .EnterState();
+ while (StateMachine.WaitRunDevsRunOps().Contains(Event.Busy)) { }
+
+ if (draining1 && StateMachine.Tank1.IsEmpty()) draining1 = false;
+ if (draining2 && StateMachine.Tank2.IsEmpty()) draining2 = false;
+ if (draining3 && StateMachine.Tank3.IsEmpty()) draining3 = false;
+ }
+
+ /// Close all drain valves
+ if (drainValves.Count > 0)
+ {
+ State.Create("Close all drain valves")
+ .AddOperation(StateMachine.ControlBoard.SetValvesOp(null, drainValves))
+ .EnterState();
+ while (StateMachine.WaitRunDevsRunOps().Contains(Event.ValvesBusy)) { }
+ }
+ }
+
+ ///
+ /// Shut down the state machine
+ ///
+ Bridge.OnActivity(this, Strings.Shutting_down_devices); /// Activity message
+
+ State.Create("No operations").EnterState(); /// Stop all operations
+ StateMachine.WaitRunDevsRunOps(true);
+
+ BenchControl.StateMachine.StopDevices(); /// Stop all devices - phase 1
+ Thread.Sleep(100);
+ BenchControl.StateMachine.StopDevices2(); /// Stop all devices - phase 2
+ }
+
+ ///
+ /// Create a new empty batch results from the procedure
+ ///
+ /// New batch number
+ /// Selected procedure
+ /// Created BatchResults
+ Results.BatchResults CreateNewBatchResults(int newBatchNr, Procedure procedure)
+ {
+ ///
+ /// Prepare new water meters
+ ///
+ foreach (var wm in WaterMeters) wm.ClearData(); /// Clean water meter data
+
+ bool compound = (StateMachine.Procedure.MetersKind == MetersKind.Combined);
+ bool heatMeters = (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter);
+ int waterMetersCount = Math.Min(WaterMeters.Count, heatMeters ? Config.Data.HeatMetersCount : (compound ? Config.Data.CompoundWMsCount : Config.Data.WMsCount));
+ ///
+ Results.Entities.WaterMeterData[] waterMeterData = new Results.Entities.WaterMeterData[waterMetersCount];
+ ///
+ int[] waterMeterParts = new int[waterMetersCount];
+ for (int wmNr = 0; wmNr < waterMetersCount; wmNr++)
+ {
+ /// WR10 .. WR15 configuration specific code (iPerl head component name)
+ TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead.IperlHead iHead =
+ TbfComponents.FindComponent(string.Format("iPerl{0}", wmNr + 1)) as TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead.IperlHead;
+
+ int ix = compound ? (2 * wmNr) : wmNr;
+ if (WaterMeters.Count > ix)
+ {
+ waterMeterParts[wmNr] = Utils.PartNr(wmNr + 1, compound);
+ waterMeterData[wmNr] = new Results.Entities.WaterMeterData()
+ {
+ ProductName = WaterMeters[ix].ProductName,
+ Producer = WaterMeters[ix].Producer,
+
+ L = WaterMeters[ix].L,
+ DN = WaterMeters[ix].DN,
+ Mounting = WaterMeters[ix].Mounting,
+
+ NewQnames = WaterMeters[ix].NewQnames,
+ Q4_Qmax = WaterMeters[ix].Q4_Qmax,
+ Q3_Qn = WaterMeters[ix].Q3_Qn,
+ Q2_Qt = WaterMeters[ix].Q2_Qt,
+ Q1_Qmin = WaterMeters[ix].Q1_Qmin,
+
+ MetrologicalClass = WaterMeters[ix].MetrologicalClass,
+ TemperatureClass = WaterMeters[ix].TemperatureClass,
+ PressureLossClass = WaterMeters[ix].PressureLossClass,
+ MaxAdmissiblePressure = WaterMeters[ix].MaxAdmissiblePressure,
+ FlowProfileSensitivityClass = WaterMeters[ix].FlowProfileSensitivityClass,
+
+ ApprovalInfo = WaterMeters[ix].ApprovalInfo,
+ Certificate = WaterMeters[ix].Certificate,
+
+ PulsesPerLtr = WaterMeters[ix].PulsesPerLtr,
+ Medium = WaterMeters[ix].Medium,
+ Text1 = WaterMeters[ix].Text1,
+ Text2 = WaterMeters[ix].Text2,
+ Text3 = WaterMeters[ix].Text3,
+ Text4 = WaterMeters[ix].Text4,
+ Text5 = WaterMeters[ix].Text5,
+
+ Compound = compound,
+ HeatMeter = heatMeters,
+#if ORACLE_DB
+ WMTypeId = (iHead != null) ? iHead.WMType_ID : 0,
+#endif
+ };
+ }
+
+ int auxIx = 2 * wmNr + 1;
+ if (compound && WaterMeters.Count > auxIx)
+ {
+ waterMeterData[wmNr].ProducerAux = WaterMeters[auxIx].Producer;
+ waterMeterData[wmNr].Q3_Qn_Aux = WaterMeters[auxIx].Q3_Qn;
+ waterMeterData[wmNr].MetrologicalClassAux = WaterMeters[auxIx].MetrologicalClass;
+ waterMeterData[wmNr].ApprovalInfoAux = WaterMeters[auxIx].ApprovalInfo;
+ }
+ }
+
+ /// Prepare empty results
+ return Results.BatchResults.NewFromProcedure(newBatchNr,
+ (BenchInfo != null) ? BenchInfo.TestBenchId : 1,
+ (BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
+ (BenchInfo != null) ? BenchInfo.Address1 : string.Empty,
+ (BenchInfo != null) ? BenchInfo.Address2 : string.Empty,
+ (BenchInfo != null) ? BenchInfo.Address3 : string.Empty,
+ (BenchInfo != null) ? BenchInfo.Address4 : string.Empty,
+ (BenchInfo != null) ? BenchInfo.Address5 : string.Empty,
+ Users.GlobalData.CurrentUser.ToEncodedStr(),
+ Users.GlobalData.CurrentUser.Number,
+ Program.Version,
+ StateMachine.Procedure,
+ waterMeterData,
+ waterMeterParts,
+ Config.Formulas.DensityCorrection(Config.Formulas.RealDensity(),
+ Config.Formulas.AtTemperature()));
+ }
+
+ ///
+ /// Reload batch results from Results database given the batch number
+ ///
+ /// Original batch number
+ /// New unique batch number
+ /// Reloaded procedure
+ ///
+ void RestoreBatchResults(int oriBatchNr, ref Results.BatchResults batchResults)
+ {
+ Batch oriBatch = Results.DB.LoadBatch(oriBatchNr);
+
+ if (oriBatch == null) return;
+
+ batchResults.Batch.StartTime = oriBatch.StartTime;
+ batchResults.Batch.TestBenchId = (BenchInfo != null) ? BenchInfo.TestBenchId : 1;
+ batchResults.Batch.TestBenchName = (BenchInfo != null) ? BenchInfo.TestBenchName : "testbench";
+
+ foreach (var testRslt in batchResults.Batch.TestRslts)
+ {
+ foreach (var oriTstRslt in oriBatch.TestRslts)
+ {
+ if (testRslt.Name() == oriTstRslt.Name() &&
+ testRslt.Part == oriTstRslt.Part &&
+ testRslt.RepetitionNr == oriTstRslt.RepetitionNr)
+ {
+ testRslt.CopyContentFrom(oriTstRslt);
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < batchResults.Batch.WaterMeters.Count; i++)
+ {
+ WaterMeter wm = batchResults.Batch.WaterMeters[i];
+ wm.Disabled = true;
+ foreach (var wm2 in oriBatch.WaterMeters)
+ {
+ if (wm.WMPosition == wm2.WMPosition)
+ {
+ wm.CopyContentFrom(wm2);
+ wm.Disabled = false;
+#if ORACLE_DB
+ wm.WaterMeterData.WMTypeId = wm2.WaterMeterData.WMTypeId;
+#endif
+ break;
+ }
+ }
+ }
+ }
+
+ void CollectSimultSteps()
+ {
+ ///
+ /// Collect steps (e.g. iPerl communication) to be done simultaneously with purging
+ ///
+ simultWithPurgingCount = 0;
+ simultWithPurgingCfg = null;
+ simultWithPurgingTests.Clear();
+ simultWithPurgingParams.Clear();
+ ///
+ foreach (var test in StateMachine.Tests)
+ {
+ Generic.IComponent testMethodComp = TbfComponents.FindComponent(test.Method);
+ if (testMethodComp == null) break;
+
+ testMethodComp.Cfg.LoadTestParamsFromDB(test);
+
+ ISimultTestMethod simultTest = testMethodComp as ISimultTestMethod;
+ MetersPath sensPath = StateMachine.GetMetersPath(test);
+
+ if (simultTest == null || !simultTest.SimultWithPrevious || sensPath == null) break;
+
+ if (simultWithPurgingCount == 0)
+ {
+ simultWithPurgingCfg = simultTest.Cfg;
+ }
+ else if (simultTest.Cfg != simultWithPurgingCfg)
+ {
+ break;
+ }
+
+ simultWithPurgingTests.Add(test);
+ simultWithPurgingParams.Add(testMethodComp.Cfg.GetRuntimeTestParamsProvider().Clone() as Generic.ITestParams);
+ simultWithPurgingCount++;
+ }
+
+ ///
+ /// Collect steps (e.g. iPerl communication) to be done simultaneously with evacuation
+ ///
+ simultWithEvacuationCount = 0;
+ simultWithEvacuationCfg = null;
+ simultWithEvacuationTests.Clear();
+ simultWithEvacuationParams.Clear();
+ ///
+ for (int i = StateMachine.Tests.Count - 1; i >= simultWithPurgingCount; i--)
+ {
+ var test = StateMachine.Tests[i];
+
+ Generic.IComponent testMethodComp = TbfComponents.FindComponent(test.Method);
+ if (testMethodComp == null) break;
+
+ testMethodComp.Cfg.LoadTestParamsFromDB(test);
+
+ ISimultTestMethod simultTest = testMethodComp as ISimultTestMethod;
+ MetersPath sensPath = StateMachine.GetMetersPath(test);
+
+ if (simultTest == null || !simultTest.SimultWithNext || sensPath == null) break;
+
+ if (simultWithEvacuationCount == 0)
+ {
+ simultWithEvacuationCfg = simultTest.Cfg;
+ }
+ else if (simultTest.Cfg != simultWithEvacuationCfg)
+ {
+ break;
+ }
+
+ simultWithEvacuationTests.Insert(0, test);
+ simultWithEvacuationParams.Insert(0, testMethodComp.Cfg.GetRuntimeTestParamsProvider().Clone() as Generic.ITestParams);
+ simultWithEvacuationCount++;
+ }
+ }
+
+ ///
+ /// Executes steps of a evacuation sequence
+ ///
+ ///
+ /// Event.Done Transition sequence completed OK
+ /// Event.UiCmdStop Transition sequence interrupted by the STOP on-screen button
+ /// Event.Error Error (e.g. RegulValveTimeOut returned by Run() of SetRegulValvePositionOp)
+ ///
+ Event DoEvacuation(TransitionSequence purgeEnd)
+ {
+ IList e;
+
+ if (simultWithEvacuationCount > 0)
+ {
+ /// Open iPerlCommunicationForm
+ ProcessData.RegisterReaders = StateMachine.GetMetersPath(simultWithEvacuationTests[0]).RegisterReaders;
+ Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, simultWithEvacuationCfg, simultWithEvacuationTests, simultWithEvacuationParams });
+ }
+
+ //--------------------------------------------------------
+ benchFilled = false; /// because evacuation sequence started
+ ///
+ switch (Transition(purgeEnd, TransitionContext.PurgeEnd))
+ {
+ case Event.Error:
+ if (simultWithEvacuationCount > 0) CloseIPerlCommForm();
+ return Event.Error;
+
+ case Event.UiCmdStop:
+ if (simultWithEvacuationCount > 0) CloseIPerlCommForm();
+ return Event.UiCmdStop;
+
+ default:
+ break;
+ }
+
+ if (simultWithEvacuationCount > 0)
+ {
+ ///
+ /// Wait until iPerl communications are completed
+ ///
+ bool completed = !(modelessDlg is GenericDevices.IHasCompleted)
+ || (modelessDlg as GenericDevices.IHasCompleted).Completed;
+ if (!completed)
+ {
+ State.Create("MainSeq : Wait until the entry form is closed")
+ .AddOperation(checkUiOp)
+ .EnterState();
+ do
+ {
+ e = StateMachine.WaitRunDevsRunOps();
+ if (e.Contains(Event.UiCmdStop))
+ {
+ CloseIPerlCommForm();
+ return Event.UiCmdStop;
+ }
+
+ completed = (modelessDlg as GenericDevices.IHasCompleted).Completed;
+ }
+ while (!completed);
+ }
+
+ modelessDlg = null;
+ }
+
+ Bridge.Bench2UI(ButtonsEtc.ShowBenchEmpty);
+
+ return Event.Done;
+ }
+ }
+}
diff --git a/TBF/BenchControl/StateMachine.cs b/TBF/BenchControl/StateMachine.cs
index f345aeb25..4f3db327c 100644
--- a/TBF/BenchControl/StateMachine.cs
+++ b/TBF/BenchControl/StateMachine.cs
@@ -548,7 +548,7 @@ namespace TBF.BenchControl
/// Loads selected procedure from the DB.
/// Updates StateMachine.Procedure and StateMachine.Tests
///
- public static bool LoadProcedure(ISession session, string procedureName, bool isRemote)
+ public static bool LoadProcedure(ISession session, string procedureName, bool isRemote, IList autoTests = null)
{
Procedure = null;
@@ -556,13 +556,32 @@ namespace TBF.BenchControl
.Where(x => (x.ProcedureState == ProcedureState.Active))
.And(x => (x.Name == procedureName))
.List();
+ if (selectedProcs.Count == 1)
+ {
+ IsRemoteProcedure = isRemote;
+ Procedure = selectedProcs[0];
- if (selectedProcs.Count != 1) return false;
+ Tests = selectedProcs[0].Tests;
+ for (int i = Tests.Count - 1; i >= 0; i--)
+ {
+ Test test = Tests[i];
+ if ((test.Name.Length > 0) && (test.Name[0] == '[') && test.Name.Contains("]"))
+ {
+ /// This is an AutoAction test => If 'actionName' is not on 'autoTests' list the test should be removed
+ int actionNameEndPos = test.Name.IndexOf(']');
+ string actionName = test.Name.Substring(1, actionNameEndPos - 1);
+ if (autoTests == null || autoTests.Count == 0 || !autoTests.Contains(actionName))
+ {
+ /// AutoAction test was not selected and should be deleted
+ Tests.RemoveAt(i);
+ }
+ }
+ }
- Procedure = selectedProcs[0];
- Tests = selectedProcs[0].Tests;
- IsRemoteProcedure = isRemote;
- return true;
+ return true;
+ }
+
+ return false;
}
public static void LoadProcedureParams(Procedure procedure)
diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj
index 769e22758..7775d2363 100644
--- a/TBF/TBF.csproj
+++ b/TBF/TBF.csproj
@@ -1111,6 +1111,7 @@
+