/// /// Copyright (c) 2013-2017 Sensus Metering Systems /// using System; using System.Collections.Generic; using log4net; using Config.Entities; using Results.Entities; using TBF.UiBridge; using TBF.BenchControl; using TBF.BenchControl.Operations; using TBF.BenchControl.GenericDevices; using TBF.Boxes; using TBF.Resources; namespace TBF.BenchControl.Sequences { public class MainSeq : SequenceBase { private static readonly ILog log = LogManager.GetLogger(typeof(MainSeq)); public override string ToString() { return "Sequences.MainSeq"; } bool benchFilled; int simultWithPurgingCount; Generic.IComponentCfg simultWithPurgingCfg; IList simultWithPurgingTests; IList simultWithPurgingParams; int simultWithEvacuationCount; Generic.IComponentCfg simultWithEvacuationCfg; IList simultWithEvacuationTests; IList simultWithEvacuationParams; System.Windows.Forms.Form modelessDlg; /// delegate void iPerlCommFormDlgt(MainSeq myRef, Generic.IComponentCfg cfg, IList tests, IList multiTestParams); /// void OpenIPerlCommForm(MainSeq myRef, Generic.IComponentCfg cfg, IList tests, IList multiTestParams) { try { /// 1nd argument TestMethods.iPerlCommunication.TestMethodCfg iPerlCfg = cfg as TestMethods.iPerlCommunication.TestMethodCfg; /// 2rd argument: as is /// 3th argument IList iPerlCommParams = new List(); foreach (var tp in multiTestParams) iPerlCommParams.Add(tp as TestMethods.iPerlCommunication.iPerlCommunicationParams); myRef.modelessDlg = new TestMethods.iPerlCommunication.iPerlCommunicationForm(iPerlCfg, tests, iPerlCommParams); myRef.modelessDlg.Show(); } catch (Exception e) { log.FatalFormat("---------------( MainSeq : OpenIperlCommForm crashed !!! )---------------"); log.FatalFormat("Message : {0}", e.Message); if (e.InnerException != null) { log.FatalFormat("InnerMessage : {0}", e.InnerException.Message); } log.FatalFormat("StackTrace : {0}{1}", Environment.NewLine, e.StackTrace); log.Fatal("--------------------------------------"); } } /// void CloseIPerlCommForm() { UiBridge.Bridge.OnCloseModelessForm(this, null); modelessDlg = null; } /// Constructor public MainSeq() { benchFilled = false; simultWithPurgingCount = 0; simultWithPurgingCfg = null; simultWithPurgingTests = new List(); simultWithPurgingParams = new List(); simultWithEvacuationCount = 0; simultWithEvacuationCfg = null; simultWithEvacuationTests = new List(); simultWithEvacuationParams = new List(); } /// /// Main sequence /// /// /// public IList Execute(Test dummyArg) { /// Operations running in more then one state checkUiOp = new CheckUIOp(true); IList e; Selection selection; StateMachine.LoadProcedure(true); // TODO: Implement as an operation so that the worker thread is not blocked //-------------------------------------------------------------------------------------------- Bridge.OnActivity(this, Strings.Starting_system); State.Create("MainSeq : Setting valves to default positions") .AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose)) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); } while (e.Contains(Event.ValvesBusy)); /// /// Read S/N-s from scales (cannot be stopped, but is limitted to Scales count x 3s (=timeout) /// IScale[] scales = new IScale[] { StateMachine.Scale1, StateMachine.Scale2, StateMachine.Scale3 }; foreach (var scale in scales) { if (scale != null) { string sn = string.Empty; IOperation getSNOp = scale.GetSerNumOp(ref sn); if (getSNOp != null) { const int nrRetries = 3; for (int i = 1; i <= nrRetries; i++) { 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) { Bridge.OnError(this, string.Format("{0} : {1}", scale.Name, Strings.Scale_communication_error)); goto error; } else { error = true; break; } } if (e.Contains(Event.TimerExpired)) { if (i == nrRetries) { Bridge.OnError(this, string.Format("{0} : {1}", scale.Name, Strings.Scale_communication_timeout)); goto error; } else { timeout = true; break; } } } while (e.Contains(Event.Busy)); if (!error && !timeout) { /// Successful if (!string.IsNullOrEmpty(sn)) log.WarnFormat("Scale {0} : s/n = {1}", scale.Name, sn); break; } State.Create(string.Format("MainSeq : Reading S/N of scale {0}", scale.Name)).EnterState(); StateMachine.WaitRunDevsRunOps(); } } } } /// /// Drain tanks for the first time, use defined drain times /// Bridge.Bench2UI(((StateMachine.DrainValve1 != null) ? ButtonsEtc.DrainTankBtn1Hi : 0) | ((StateMachine.DrainValve2 != null) ? ButtonsEtc.DrainTankBtn2Hi : 0) | ((StateMachine.DrainValve3 != null) ? ButtonsEtc.DrainTankBtn3Hi : 0)); IntBox remainingTime = new IntBox(); State startNew = State.Create("MainSeq : Drain tanks") .AddOperation(checkUiOp); IList allDrainValves = new List(); if (StateMachine.DrainValve1 != null) allDrainValves.Add(StateMachine.DrainValve1); if (StateMachine.DrainValve2 != null) allDrainValves.Add(StateMachine.DrainValve2); if (StateMachine.DrainValve3 != null) allDrainValves.Add(StateMachine.DrainValve3); // Determine the tank emptying time (the maximum for all balances) int scaleDrainTime = 0; if (StateMachine.Scale1 != null && StateMachine.Scale1.EmptyTimeSec > scaleDrainTime) { scaleDrainTime = StateMachine.Scale1.EmptyTimeSec; } if (StateMachine.Scale2 != null && StateMachine.Scale2.EmptyTimeSec > scaleDrainTime) { scaleDrainTime = StateMachine.Scale2.EmptyTimeSec; } if (StateMachine.Scale3 != null && StateMachine.Scale3.EmptyTimeSec > scaleDrainTime) { scaleDrainTime = StateMachine.Scale3.EmptyTimeSec; } if (scaleDrainTime > 0) { startNew.AddOperation(new TimerOp(scaleDrainTime, remainingTime)) .AddOperation(StateMachine.ControlBoard.SetValvesOp(allDrainValves, null)); } startNew.EnterState(); do { Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Emptying_tank, remainingTime.Val / 60, "min", remainingTime.Val % 60, Strings.sec)); e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) goto error; bool stopDrainingCmd = e.Contains(Event.UiCmdStopDrainingTank1) || e.Contains(Event.UiCmdStopDrainingTank2) || e.Contains(Event.UiCmdStopDrainingTank3); if (stopDrainingCmd && !e.Contains(Event.ValvesBusy) && !e.Contains(Event.CameraBusy)) { goto stop_draining; } } while (e.Contains(Event.TimerBusy) || e.Contains(Event.CameraBusy) || e.Contains(Event.ValvesBusy)); if (e.Contains(Event.CameraOpFailed)) goto error; /// TODO: resolve in some other way Bridge.OnActivity(this, Strings.Emptying_tank); stop_draining: 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)) goto error; } while (e.Contains(Event.ValvesBusy)); //-------------------------------------------------------------------------------------------- Bridge.OnActivity(this, Strings.Resetting_scales); //-------------------------------------------------------------------------------------------- Bridge.Bench2UI(ButtonsEtc.StopBtnEn); DoubleBox tara1 = new DoubleBox(0); DoubleBox tara2 = new DoubleBox(0); DoubleBox tara3 = new DoubleBox(0); State.Create("MainSeq : Reset scales").AddOperation(checkUiOp) .AddOperation((StateMachine.Scale1 != null) ? StateMachine.Scale1.TaringOp(ref tara1) : null) .AddOperation((StateMachine.Scale2 != null) ? StateMachine.Scale2.TaringOp(ref tara2) : null) .AddOperation((StateMachine.Scale3 != null) ? StateMachine.Scale3.TaringOp(ref tara3) : null) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) goto error; if (e.Contains(Event.UiCmdStop)) goto stop; } while (e.Contains(Event.Busy)); //-------------------------------------------------------------------------------------------- Bridge.OnActivity(this, Strings.Measuring_the_weight); State.Create("MainSeq : Mesuring the weight for the 1st time") .AddOperation(checkUiOp) .AddOperation(new MettlerToledo.ReadMassesOp()) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) goto error; if (e.Contains(Event.UiCmdStop)) goto stop; } while (!e.Contains(Event.BalanceDone)); //-------------------------------------------------------------------------------------------- select_procedure: CloseBeginForm(); /// Make sure the CycleBeginForm is closed (after an abnormal end, etc.) do { selection = MakeSelection(MKSelContext.ProcedureNotSelected); StateMachine.LoadProcedure(false); } while (StateMachine.Procedure == null); /// Make sure a valid procedure is selected /// /// Procedure selected at this point, a new batch was started /// StateMachine.LoadProcedureParams(StateMachine.Procedure); StateMachine.ControlBoard.ManualUIAllowed = !StateMachine.Procedure.ManualCtrlDisabled; Bridge.Bench2UI(ButtonsEtc.StopBtnEn); /// Enable STOP button int newBatchNr = Program.LocalSettings.BatchNr; log.FatalFormat("New measurement session started: batch = {0}, procedure = {1}", newBatchNr, StateMachine.Procedure.Name); if (selection == Selection.RestoreBatch) { BatchRslts = CreateNewBatchResults(newBatchNr, StateMachine.Procedure); RestoreBatchResults(TBF.UiBridge.Bridge.BatchNr, ref BatchRslts); /// pass the original batch number of the batch to be restored } else if (selection == Selection.Custom) { for (int i = StateMachine.Procedure.Tests.Count - 1; i >= 0; i--) { if (StateMachine.Procedure.Tests[i].Name.ToLower().Contains("write") || StateMachine.Procedure.Tests[i].Name.ToLower().Contains("reset")) { StateMachine.Procedure.Tests.RemoveAt(i); } } BatchRslts = CreateNewBatchResults(newBatchNr, StateMachine.Procedure); for (int i = StateMachine.Procedure.Tests.Count - 1; i >= 0; i--) { if (StateMachine.Procedure.Tests[i].Name.ToLower().Contains("adj")) { StateMachine.Procedure.Tests.RemoveAt(i); } } } else { BatchRslts = CreateNewBatchResults(newBatchNr, StateMachine.Procedure); } StateMachine.CycleStartTimeStamp = BatchRslts.Batch.StartTime; Bridge.OnProcedureSelected(this, new ProcedureSelectedEventArgs(StateMachine.Procedure)); /// /// Display 'Cycle Begin Form' in case of a normal batch (not a restored batch) /// if (selection != Selection.RestoreBatch && selection != Selection.Custom) { if (OpenCycleBeginForm()) goto stop; } /// Find purge suquences TransitionSequence purgeBegin = null; TransitionSequence purgeEnd = null; foreach (var transition in StateMachine.TransitionSequences) { if (transition.Name == StateMachine.Procedure.TransitionStart) purgeBegin = transition; if (transition.Name == StateMachine.Procedure.TransitionEnd) purgeEnd = transition; } if (selection == Selection.Q1 || selection == Selection.Q2 || selection == Selection.Q3 || selection == Selection.Test) { goto assume_bench_filled; } else if ((selection == Selection.Cycle && benchFilled) || (selection == Selection.RestoreBatch)) { /// /// Always ask a question in case of a restored batch /// State.Create("MainSeq : Answer a question") .AddOperation(new Operations.AskYesNoOp(Strings.Fill_with_water)) .AddOperation(checkUiOp) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.No)) goto assume_bench_filled; if (e.Contains(Event.UiCmdStop)) goto select_procedure; } while (!e.Contains(Event.Yes)); } fill_the_bench: CollectSimultSteps(); /// if (simultWithPurgingCount > 0) { /// Make sure the entry form is closed if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stop; /// Open iPerlCommunicationForm ProcessData.RegisterReaders = StateMachine.GetMetersPath(simultWithPurgingTests[0]).RegisterReaders; Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, simultWithPurgingCfg, simultWithPurgingTests, simultWithPurgingParams }); } /// /// Purging @ cycle start /// Event evt = Transition(purgeBegin, TransitionContext.PurgeBegin); /// switch (evt) { case Event.Error: if (simultWithPurgingCount > 0) CloseIPerlCommForm(); goto error; case Event.UiCmdStop: if (simultWithPurgingCount > 0) CloseIPerlCommForm(); goto stop; default: break; } if (simultWithPurgingCount > 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(); goto stop; } completed = (modelessDlg as GenericDevices.IHasCompleted).Completed; } while (!completed); } modelessDlg = null; if (selection == Selection.Custom) { /// Load existing data from databases Results.DBase.Databases.Clear(); try { Results.DBase.Databases.Add(new Results.DBase("SERVER=10.42.128.197; DATABASE=st-wr10-r; UID=vysledky; PASSWORD=GAqx76QUB6NbnpZP; CHARSET=utf8;", "WR10")); } catch (Exception exc) { log.ErrorFormat("Cannot open WR10 result database: {0}", exc.Message); } try { Results.DBase.Databases.Add(new Results.DBase("SERVER=10.42.128.98; DATABASE=st-wr11-r; UID=vysledky; PASSWORD=GAqx76QUB6NbnpZP; CHARSET=utf8;", "WR11")); } catch (Exception exc) { log.ErrorFormat("Cannot open WR11 result database: {0}", exc.Message); } try { Results.DBase.Databases.Add(new Results.DBase("SERVER=10.42.128.152; DATABASE=st-wr13-r; UID=vysledky; PASSWORD=GAqx76QUB6NbnpZP; CHARSET=utf8;", "WR13")); } catch (Exception exc) { log.ErrorFormat("Cannot open WR13 result database: {0}", exc.Message); } try { Results.DBase.Databases.Add(new Results.DBase("SERVER=10.42.128.63; DATABASE=st-wr15-r; UID=vysledky; PASSWORD=GAqx76QUB6NbnpZP; CHARSET=utf8;", "WR15")); } catch (Exception exc) { log.ErrorFormat("Cannot open WR15 result database: {0}", exc.Message); } for (int i = 0; i < BatchRslts.WaterMeters.Length; i++) { WaterMeter newWM = BatchRslts.WaterMeters[i]; for (int j = 0; j < Results.DBase.Count; j++) { NHibernate.ISession session = Results.DBase.Databases[j].OpenSession(); IList watermeters = session.QueryOver().Where(x => (x.SerialNr == newWM.SerialNr)).List(); if (watermeters.Count > 0) { BatchRslts.WaterMeters[i].CopyContentFrom(watermeters[watermeters.Count - 1]); /// Copy results from the last occurance of the watermeter } } } } } assume_bench_filled: benchFilled = true; Bridge.Bench2UI(ButtonsEtc.ShowBenchFilled); if (selection != Selection.PurgeBegin && selection != Selection.RestoreBatch && selection != Selection.Custom) { goto cycle_or_test_selected; } select_cycle_or_test: //---------------------------------------------------------- selection = MakeSelection(MKSelContext.InsideProcedure); /// if (selection == Selection.PurgeBegin) goto fill_the_bench; if (selection == Selection.PurgeEnd) { switch (DoEvacuation(purgeEnd)) { case Event.Error: goto error; case Event.UiCmdStop: goto stop; default: goto select_cycle_or_test; } } if (selection == Selection.Break) { StateMachine.ControlBoard.ManualUIAllowed = true; Bridge.Bench2UI(ButtonsEtc.ShowBenchEmpty); Bridge.OnProcedureCompleted(this, new ProcedureCompletedEventArgs(StateMachine.Procedure)); goto select_procedure; } if (selection == Selection.SaveResults) goto save_results; cycle_or_test_selected: UiBridge.Bridge.OnError(this, string.Empty); /// Clear an error message (if any) if (UIFlowControl.Stop == WaitBeginFormClosed()) { goto stop_within_cycle; /// Make sure the entry form is closed } Bridge.Bench2UI(ButtonsEtc.StopBtnEn); /// Hide buttons if (selection != Selection.Cycle) { //-------------------------------- State.Create("MainSeq : Continue in the cycle?") .AddOperation(new Operations.AskYesNoOp(Strings.Continue_in_the_cycle)) .AddOperation(checkUiOp) .EnterState(); while (true) { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Yes)) { selection = Selection.RestOfCycle; break; } if (e.Contains(Event.No)) break; if (e.Contains(Event.UiCmdStop)) goto select_procedure; } } if (selection == Selection.Cycle) { float TimeEstimateTotal; /// Time estimate of the selected cycle or test TimeEstimateTotal = 0; for (int i = simultWithPurgingCount; i < StateMachine.Tests.Count - simultWithEvacuationCount; i++) { Test test = StateMachine.Tests[i]; TimeEstimateTotal += (test.Repeats * (test.TstTime + 10.0f)); /// Try to fetch all test paths and transitions /// to detect configuration errors as early as possible. string errorMsg; TBF.BenchControl.Generic.IComponent testMethod = TbfComponents.FindComponent(test.Method); if (!(testMethod is TBF.BenchControl.TestMethods.OuterLoop.Start.Component) && !(testMethod is TBF.BenchControl.TestMethods.OuterLoop.End.Component) && !StateMachine.GetPaths(test, (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter), out inPath, out benchPath, out outPath, out sensPath, out heatMetersPath, out transitionBefore, out transitionAfter, out errorMsg)) { UiBridge.Bridge.OnError(this, errorMsg); goto select_cycle_or_test; } } int currentTestIx = simultWithPurgingCount; int outerLoopStartIx = currentTestIx; bool outerLoopMode = false; int outerLoopCounter = 0; while (currentTestIx < StateMachine.Tests.Count - simultWithEvacuationCount) { Test test = StateMachine.Tests[currentTestIx]; /// Fetch the test paths and transitions string errorMsg; TBF.BenchControl.Generic.IComponent testMethod = TbfComponents.FindComponent(test.Method); if (!(testMethod is TBF.BenchControl.TestMethods.OuterLoop.Start.Component) && !(testMethod is TBF.BenchControl.TestMethods.OuterLoop.End.Component) && !StateMachine.GetPaths(test, (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter), out inPath, out benchPath, out outPath, out sensPath, out heatMetersPath, out transitionBefore, out transitionAfter, out errorMsg)) { UiBridge.Bridge.OnError(this, errorMsg); goto select_cycle_or_test; } /// Update format for the water mass Mass.Format = outPath.Scale.Format; StartMass.Format = outPath.Scale.Format; EndMass.Format = outPath.Scale.Format; //-------------------------------------------------------------- ITestMethod testMethodSequence = TbfComponents.FindComponent(test.Method) as ITestMethod; if (testMethodSequence != null && testMethodSequence.CanTest(StateMachine.Procedure.MetersKind)) { StateMachine.LoadTestParams(test); ProcessData.RegisterReaders = sensPath.RegisterReaders; foreach (var rr in sensPath.RegisterReaders) { if (rr is TestMethods.iPerlCommunication.iPerlHead.IperlHead && BenchInfo != null) { (rr as TestMethods.iPerlCommunication.iPerlHead.IperlHead).BenchName = BenchInfo.TestBenchName; } } e = testMethodSequence.Execute(test, outerLoopMode, outerLoopCounter); if (e.Contains(Event.ConfigurationError)) { outerLoopMode = false; outerLoopCounter = 0; goto select_cycle_or_test; } else if (e.Contains(Event.Error)) { outerLoopMode = false; outerLoopCounter = 0; goto error; } else if (e.Contains(Event.OpArgumentError)) { outerLoopMode = false; outerLoopCounter = 0; goto config_error; } else if (e.Contains(Event.UiCmdStop)) { outerLoopMode = false; outerLoopCounter = 0; goto stop_within_cycle; } else if (e.Contains(Event.OuterLoopStart)) { outerLoopMode = true; outerLoopCounter = 1; outerLoopStartIx = currentTestIx; } else if (e.Contains(Event.OuterLoopNext)) { outerLoopCounter++; currentTestIx = outerLoopStartIx; } else if (e.Contains(Event.OuterLoopEnd)) { outerLoopMode = false; outerLoopCounter = 0; } } else { UiBridge.Bridge.OnError(this, string.Format(Strings.Method_0_cannot_be_used, test.Method)); goto select_cycle_or_test; } currentTestIx++; } } else if (selection == Selection.RestOfCycle) { Test slctdTest = TBF.BenchControl.StateMachine.GetTest(selection); if (slctdTest == null) { UiBridge.Bridge.OnError(this, string.Format("No test specified")); goto select_cycle_or_test; } int selsctedTestIx = -1; for (int i = simultWithPurgingCount; i < StateMachine.Tests.Count - simultWithEvacuationCount; i++) { if (slctdTest == StateMachine.Tests[i]) { selsctedTestIx = i; break; } } if (selsctedTestIx == -1) goto select_cycle_or_test; float TimeEstimateTotal; /// Time estimate of the selected cycle or test TimeEstimateTotal = 0; for (int i = selsctedTestIx; i < StateMachine.Tests.Count - simultWithEvacuationCount; i++) { Test test = StateMachine.Tests[i]; TimeEstimateTotal += (test.Repeats * (test.TstTime + 10.0f)); /// Try to fetch all test paths and transitions /// to detect configuration errors as early as possible. string errorMsg; TBF.BenchControl.Generic.IComponent testMethod = TbfComponents.FindComponent(test.Method); if (!(testMethod is TBF.BenchControl.TestMethods.OuterLoop.Start.Component) && !(testMethod is TBF.BenchControl.TestMethods.OuterLoop.End.Component) && !StateMachine.GetPaths(test, (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter), out inPath, out benchPath, out outPath, out sensPath, out heatMetersPath, out transitionBefore, out transitionAfter, out errorMsg)) { UiBridge.Bridge.OnError(this, errorMsg); goto select_cycle_or_test; } } int currentTestIx = selsctedTestIx; int outerLoopStartIx = currentTestIx; bool outerLoopMode = false; int outerLoopCounter = 0; while (currentTestIx < StateMachine.Tests.Count - simultWithEvacuationCount) { Test test = StateMachine.Tests[currentTestIx]; /// Fetch the test paths and transitions string errorMsg; TBF.BenchControl.Generic.IComponent testMethod = TbfComponents.FindComponent(test.Method); if (!(testMethod is TBF.BenchControl.TestMethods.OuterLoop.Start.Component) && !(testMethod is TBF.BenchControl.TestMethods.OuterLoop.End.Component) && !StateMachine.GetPaths(test, (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter), out inPath, out benchPath, out outPath, out sensPath, out heatMetersPath, out transitionBefore, out transitionAfter, out errorMsg)) { UiBridge.Bridge.OnError(this, errorMsg); goto select_cycle_or_test; } /// Update format for the water mass Mass.Format = outPath.Scale.Format; StartMass.Format = outPath.Scale.Format; EndMass.Format = outPath.Scale.Format; //-------------------------------------------------------------- ITestMethod testMethodSequence = TbfComponents.FindComponent(test.Method) as ITestMethod; if (testMethodSequence != null && testMethodSequence.CanTest(StateMachine.Procedure.MetersKind)) { StateMachine.LoadTestParams(test); ProcessData.RegisterReaders = sensPath.RegisterReaders; foreach (var rr in sensPath.RegisterReaders) { if ((rr is TestMethods.iPerlCommunication.iPerlHead.IperlHead) && (BenchInfo != null)) { (rr as TestMethods.iPerlCommunication.iPerlHead.IperlHead).BenchName = BenchInfo.TestBenchName; } } e = testMethodSequence.Execute(test, outerLoopMode, outerLoopCounter); if (e.Contains(Event.ConfigurationError)) { outerLoopMode = false; outerLoopCounter = 0; goto select_cycle_or_test; } else if (e.Contains(Event.Error)) { outerLoopMode = false; outerLoopCounter = 0; goto error; } else if (e.Contains(Event.OpArgumentError)) { outerLoopMode = false; outerLoopCounter = 0; goto config_error; } else if (e.Contains(Event.UiCmdStop)) { outerLoopMode = false; outerLoopCounter = 0; goto stop_within_cycle; } else if (e.Contains(Event.OuterLoopStart)) { outerLoopMode = true; outerLoopCounter = 1; outerLoopStartIx = currentTestIx; } else if (e.Contains(Event.OuterLoopNext)) { outerLoopCounter++; currentTestIx = outerLoopStartIx; } else if (e.Contains(Event.OuterLoopEnd)) { outerLoopMode = false; outerLoopCounter = 0; } } else { UiBridge.Bridge.OnError(this, string.Format("{0} cannot be used", test.Method)); goto select_cycle_or_test; } currentTestIx++; } } else /// if (selection == Selection.Test) { Test test = TBF.BenchControl.StateMachine.GetTest(selection); if (test == null) { UiBridge.Bridge.OnError(this, string.Format("No test specified")); goto select_cycle_or_test; } /// Fetch the test paths and transitions string errorMsg; TBF.BenchControl.Generic.IComponent testMethod = TbfComponents.FindComponent(test.Method); if (!(testMethod is TBF.BenchControl.TestMethods.OuterLoop.Start.Component) && !(testMethod is TBF.BenchControl.TestMethods.OuterLoop.End.Component) && !StateMachine.GetPaths(test, (StateMachine.Procedure.MetersKind == MetersKind.HeatMeter), out inPath, out benchPath, out outPath, out sensPath, out heatMetersPath, out transitionBefore, out transitionAfter, out errorMsg)) { UiBridge.Bridge.OnError(this, errorMsg); goto select_cycle_or_test; } /// Update format for the water mass Mass.Format = outPath.Scale.Format; StartMass.Format = outPath.Scale.Format; EndMass.Format = outPath.Scale.Format; ITestMethod testMethodSequence = TbfComponents.FindComponent(test.Method) as ITestMethod; if (testMethodSequence != null && testMethodSequence.CanTest(StateMachine.Procedure.MetersKind)) { StateMachine.LoadTestParams(test); ProcessData.RegisterReaders = sensPath.RegisterReaders; foreach (var rr in sensPath.RegisterReaders) { if ((rr is TestMethods.iPerlCommunication.iPerlHead.IperlHead) && (BenchInfo != null)) { (rr as TestMethods.iPerlCommunication.iPerlHead.IperlHead).BenchName = BenchInfo.TestBenchName; } } e = testMethodSequence.Execute(test, false, 0); if (e.Contains(Event.Error)) goto error; if (e.Contains(Event.OpArgumentError)) goto config_error; if (e.Contains(Event.UiCmdStop)) goto stop_within_cycle; } else { UiBridge.Bridge.OnError(this, string.Format("{0} cannot be used", test.Method)); goto select_cycle_or_test; } } goto select_cycle_or_test; save_results: UiBridge.Bridge.OnError(this, string.Empty); /// Clear an error message (if any) Bridge.Bench2UI(ButtonsEtc.StopBtnEn); /// Hide the most of buttons if (State.LastEvents.Contains(Event.ModelessFormIsOpen)) { if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stop; } else if (State.LastEvents.Contains(Event.ModelessFormClosed)) { CloseBeginForm(); } Bridge.OnActivity(this, Strings.Enter_protocol_data); //-------------------------------- GenericDevices.IDataEntry dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IDataEntry; if (dataEntryCmpnt != null) { if (dataEntryCmpnt is IHasCycleEndForm) { /// Open the modeless form for the end of the cycle State.Create("MainSeq : Enter end data") .AddOperation((dataEntryCmpnt as GenericDevices.IHasCycleEndForm).ShowCycleEndFormOp()) .AddOperation(checkUiOp) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.UiCmdStop)) goto stop; } while (!e.Contains(Event.ModelessFormClosed)); } dataEntryCmpnt.UpdateTestResults(BatchRslts); } ProcessData.BatchRslts.Batch.EndTime = DateTime.Now; ProcessData.BatchRslts.AddWaterMetersToBatch(); //------------------------------------------------------ Bridge.OnActivity(this, Strings.Saving_and_printing_results); State savingAndPrintingRslts = State.Create("MainSeq : Saving and printing results"); string[] writers = StateMachine.Procedure.ResultsWriter.Split(new char[] { '~' }); foreach (var writerName in writers) { IResultsWriter writer = TbfComponents.FindComponent(writerName) as IResultsWriter; if (writer != null) { try { savingAndPrintingRslts.AddOperation(writer.WriteResultsOp(ProcessData.BatchRslts.Batch)); } catch (Exception exc) { Bridge.OnError(this, string.Format(Strings.Component_0_crashed_Results_not_saved, writerName)); log.FatalFormat("FileWriter {0} crashed: {1}", writerName, exc.Message); } } } string[] printers = StateMachine.Procedure.ResultsPrinter.Split(new char[] { '~' }); foreach (var printerName in printers) { IResultsPrinter printer = TbfComponents.FindComponent(printerName) as IResultsPrinter; if (printer != null && !printer.SupressPrinting) { try { savingAndPrintingRslts.AddOperation(printer.PrintResultsOp(ProcessData.BatchRslts.Batch)); } catch (Exception exc) { Bridge.OnError(this, string.Format(Strings.Component_0_crashed_Results_not_printed, printerName)); log.FatalFormat("Printer {0} crashed: {1}", printerName, exc.Message); } } } savingAndPrintingRslts.AddOperation(checkUiOp).EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) goto error; if (e.Contains(Event.UiCmdStop)) goto stop; } while (e.Contains(Event.Busy)); bool resultsSent = !e.Contains(Event.ResultsNotWritten); ProcessData.BatchRslts.Batch.RsltsSent = resultsSent; /// /// Save results to the built in 'Results' database /// Results.DB.SaveNewBatch(ProcessData.BatchRslts.Batch); /// /// Save results to 'summary results' logger /// foreach (var tr in ProcessData.BatchRslts.Batch.TestRslts) { summaryResults.Info(TestResult2CsvLine(tr)); } Program.LocalSettings.BatchNr++; Program.LocalSettings.Save(); log.FatalFormat("Measurement session saved: batch = {0}, procedure = {1}, next batch nr. = {2}", ProcessData.BatchRslts.Batch.BatchNr, ProcessData.BatchRslts.Batch.ProcedureName, Program.LocalSettings.BatchNr); evacuation: /// Evacuation is similar to 'Abort session' (no results are saved), but the evacuation is done as well. StateMachine.ControlBoard.ManualUIAllowed = true; switch (DoEvacuation(purgeEnd)) { case Event.Error: goto error; case Event.UiCmdStop: goto stop; default: break; } Bridge.OnProcedureCompleted(this, new ProcedureCompletedEventArgs(StateMachine.Procedure)); goto select_procedure; stop_within_cycle: //-------------------------------- State.Create("MainSeq : Turning IDLE -> Closing the valves") .AddOperation(checkUiOp) .AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose)) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) goto error; } while (!e.Contains(Event.ValvesSet)); goto select_cycle_or_test; stop: //-------------------------------- State.Create("MainSeq : Turning IDLE -> Closing the valves") .AddOperation(checkUiOp) .AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose)) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) goto error; } while (!e.Contains(Event.ValvesSet)); goto select_procedure; config_error: //-------------------------------- State.Create("MainSeq : Procedure configuration error") .AddOperation(checkUiOp) .AddOperation(new Operations.MessageBoxOp("Test configration error")) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); } while (!e.Contains(Event.OK)); goto select_cycle_or_test; error: //-------------------------------- State.Create("MainSeq : ERROR -> Closing the valves") .AddOperation(checkUiOp) .AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose)) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); } while (!e.Contains(Event.ValvesSet) && !e.Contains(Event.Error)); //-------------------------------- State.Create("MainSeq : ERROR state") .EnterState(); while (true) StateMachine.WaitRunDevsRunOps(); } /// /// MakeSelection() call context /// enum MKSelContext { ProcedureNotSelected, InsideProcedure, } /// /// Return values of MakeSelection() /// public enum Selection { PurgeBegin, PurgeEnd, Break, Cycle, RestOfCycle, Test, Q1, Q2, Q3, SaveResults, RestoreBatch, Custom, } /// /// 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 /// private Selection MakeSelection(MKSelContext context) { /// 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) | (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.Scale1 != null) ? StateMachine.Scale1.ReadMassOp(ref mass1) : null) .AddOperation((StateMachine.Scale2 != null) ? StateMachine.Scale2.ReadMassOp(ref mass2) : null) .AddOperation((StateMachine.Scale3 != null) ? StateMachine.Scale3.ReadMassOp(ref mass3) : null) .AddOperation(StateMachine.ControlBoard.UpdateTankWeightOp()) .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.Scale1.IsEmpty(mass1.Val)) break; if (draining2 && StateMachine.Scale2.IsEmpty(mass2.Val)) break; if (draining3 && StateMachine.Scale3.IsEmpty(mass3.Val)) break; /// Quit the selection loop and leave MakeSelection() if (e.Contains(Event.UiCmdBreak) && context == MKSelContext.InsideProcedure) 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.UiCmdCustom)) return Selection.Custom; } while (true); if (e.Contains(Event.Error)) { ///------------------------------------ Bridge.OnActivity(this, Strings.Error); ///------------------------------------ State.Create("MainSeq : ERROR state") .EnterState(); while (true) StateMachine.WaitRunDevsRunOps(); /// Endless loop } else { string stateText = "MainSeq : "; IList openValves = new List(); IList closeValves = new List(); if (draining1 && (StateMachine.Scale1.IsEmpty(mass1.Val) || e.Contains(Event.UiCmdStopDrainingTank1))) { draining1 = false; closeValves.Add(StateMachine.DrainValve1); stateText = stateText + "close tank 1, "; } else if (draining2 && (StateMachine.Scale2.IsEmpty(mass2.Val) || e.Contains(Event.UiCmdStopDrainingTank2))) { draining2 = false; closeValves.Add(StateMachine.DrainValve2); stateText = stateText + "close tank 2, "; } else if (draining3 && (StateMachine.Scale3.IsEmpty(mass3.Val) || 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)); } } } /// /// 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++) { 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, 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, Text1 = WaterMeters[ix].Text1, Text2 = WaterMeters[ix].Text2, Text3 = WaterMeters[ix].Text3, Text4 = WaterMeters[ix].Text4, Text5 = WaterMeters[ix].Text5, Compound = compound, HeatMeter = heatMeters, }; } 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; } #if ORACLE_DB BenchControl.WaterMeters.WaterMeter.WaterMeter iPerl = WaterMeters[wmNr] as BenchControl.WaterMeters.WaterMeter.WaterMeter; if (iPerl != null) { waterMeterData[wmNr].WMTypeId = iPerl.WMType_ID; waterMeterData[wmNr].WMTypeRev = iPerl.WMType_Rev; } #endif } /// Prepare empty results return Results.BatchResults.NewFromProcedure(newBatchNr, (BenchInfo != null) ? BenchInfo.TestBenchId : 1, Users.GlobalData.CurrentUser.UserName, Users.GlobalData.CurrentUser.Number, Program.Version, StateMachine.Procedure, waterMeterData, waterMeterParts, Formulas.DensityCorrection(Program.LocalSettings.RealDensity, Program.LocalSettings.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); batchResults.Batch.StartTime = oriBatch.StartTime; 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.WaterMeters.Length; i++) { WaterMeter wm = batchResults.WaterMeters[i]; foreach (var wm2 in oriBatch.WaterMeters) { if (wm.WMPosition == wm2.WMPosition) { wm.CopyContentFrom(wm2); 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.UpdateTestParams(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.GetTestParams().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.UpdateTestParams(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.GetTestParams().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 }); } //-------------------------------------------------------- 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; } benchFilled = false; Bridge.Bench2UI(ButtonsEtc.ShowBenchEmpty); return Event.Done; } } }