1427 lines
53 KiB
C#
1427 lines
53 KiB
C#
///
|
|
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using log4net;
|
|
using Config.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"; }
|
|
|
|
|
|
int simultWithPurgingCount;
|
|
Generic.IComponentCfg simultWithPurgingCfg;
|
|
IList<Config.Entities.Test> simultWithPurgingTests;
|
|
IList<Generic.ITestParams> simultWithPurgingParams;
|
|
|
|
int simultWithEvacuationCount;
|
|
Generic.IComponentCfg simultWithEvacuationCfg;
|
|
IList<Config.Entities.Test> simultWithEvacuationTests;
|
|
IList<Generic.ITestParams> simultWithEvacuationParams;
|
|
|
|
|
|
|
|
System.Windows.Forms.Form modelessDlg;
|
|
///
|
|
delegate void iPerlCommFormDlgt(MainSeq myRef, Generic.IComponentCfg cfg, IList<Test> tests, IList<Generic.ITestParams> multiTestParams);
|
|
///
|
|
void OpenIPerlCommForm(MainSeq myRef, Generic.IComponentCfg cfg, IList<Test> tests, IList<Generic.ITestParams> multiTestParams)
|
|
{
|
|
try
|
|
{
|
|
/// 1nd argument
|
|
TestMethods.iPerlCommunication.TestMethodCfg iPerlCfg = cfg as TestMethods.iPerlCommunication.TestMethodCfg;
|
|
|
|
/// 2rd argument: as is
|
|
|
|
/// 3th argument
|
|
IList<TestMethods.iPerlCommunication.iPerlCommunicationParams> iPerlCommParams = new List<TestMethods.iPerlCommunication.iPerlCommunicationParams>();
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
/// <summary> Constructor </summary>
|
|
public MainSeq()
|
|
{
|
|
simultWithPurgingTests = new List<Config.Entities.Test>();
|
|
simultWithPurgingParams = new List<Generic.ITestParams>();
|
|
simultWithEvacuationTests = new List<Config.Entities.Test>();
|
|
simultWithEvacuationParams = new List<Generic.ITestParams>();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Main sequence
|
|
/// </summary>
|
|
/// <param name="dummyArg"></param>
|
|
/// <returns></returns>
|
|
public IList<Event> Execute(Test dummyArg)
|
|
{
|
|
/// Operations running in more then one state
|
|
checkUiOp = new CheckUIOp(true);
|
|
|
|
IList<Event> e;
|
|
Selection selection;
|
|
bool benchFilled = false;
|
|
|
|
simultWithPurgingCount = 0;
|
|
simultWithPurgingCfg = null;
|
|
simultWithPurgingTests.Clear();
|
|
simultWithPurgingParams.Clear();
|
|
|
|
simultWithEvacuationCount = 0;
|
|
simultWithEvacuationCfg = null;
|
|
simultWithEvacuationTests.Clear();
|
|
simultWithEvacuationParams.Clear();
|
|
|
|
StateMachine.LoadProcedure(true); // TODO: Implement as an operation so that the worker thread is not blocked
|
|
|
|
Bridge.Bench2UI(ButtonsEtc.StopBtnEn);
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
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));
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
IntBox remainingTime = new IntBox();
|
|
State startNew = State.Create("MainSeq : Emptying tanks")
|
|
.AddOperation(checkUiOp);
|
|
IList<IValve> allDrainValves = new List<IValve>();
|
|
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;
|
|
if (e.Contains(Event.UiCmdStop) &&
|
|
!e.Contains(Event.ValvesBusy) &&
|
|
!e.Contains(Event.CameraBusy))
|
|
{
|
|
goto stop_emptying;
|
|
}
|
|
}
|
|
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_emptying:
|
|
//--------------------------------------------------------------------------------------------
|
|
State stopEmptying = State.Create("MainSeq : Stop emptying of water tanks")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, allDrainValves))
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) goto error;
|
|
if (e.Contains(Event.UiCmdStop)) goto stop;
|
|
}
|
|
while (e.Contains(Event.ValvesBusy));
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
State taraAll = State.Create("MainSeq : Reset all balances").AddOperation(checkUiOp);
|
|
DoubleBox tara = new DoubleBox(0);
|
|
if (StateMachine.Scale1 != null) taraAll.AddOperation(StateMachine.Scale1.TaringOp(ref tara));
|
|
if (StateMachine.Scale2 != null) taraAll.AddOperation(StateMachine.Scale2.TaringOp(ref tara));
|
|
if (StateMachine.Scale3 != null) taraAll.AddOperation(StateMachine.Scale3.TaringOp(ref tara));
|
|
taraAll.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);
|
|
|
|
Bridge.Bench2UI(ButtonsEtc.StopBtnEn); /// Enable STOP button
|
|
|
|
if (selection == Selection.RestoreBatch)
|
|
{
|
|
BatchRslts = RestoreBatchResults(TBF.UiBridge.Bridge.BatchNr, /// Original batch number
|
|
Program.LocalSettings.BatchNr, /// New batch number
|
|
StateMachine.Procedure);
|
|
}
|
|
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(Program.LocalSettings.BatchNr, 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(Program.LocalSettings.BatchNr, 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); }
|
|
|
|
foreach (var wm in BatchRslts.WaterMeters)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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) goto evacuation;
|
|
if (selection == Selection.Break)
|
|
{
|
|
Bridge.Bench2UI(ButtonsEtc.ShowBenchEmpty);
|
|
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 WaterMeters.iPerl.WaterMeter) && (BenchInfo != null))
|
|
{
|
|
(rr as WaterMeters.iPerl.WaterMeter).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 WaterMeters.iPerl.WaterMeter) && (BenchInfo != null))
|
|
{
|
|
(rr as WaterMeters.iPerl.WaterMeter).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 WaterMeters.iPerl.WaterMeter) && (BenchInfo != null))
|
|
{
|
|
(rr as WaterMeters.iPerl.WaterMeter).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;
|
|
}
|
|
}
|
|
|
|
if (BatchRslts.AllTestsDone())
|
|
{
|
|
Bridge.Bench2UI(ButtonsEtc.AcceptResultsBtnEn | ButtonsEtc.ResetResultsBtnEn);
|
|
}
|
|
else
|
|
{
|
|
Bridge.Bench2UI(ButtonsEtc.ResetResultsBtnEn);
|
|
}
|
|
|
|
goto select_cycle_or_test;
|
|
|
|
evacuation:
|
|
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("BatchNr = {0} (incremented)", Program.LocalSettings.BatchNr);
|
|
|
|
|
|
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();
|
|
goto error;
|
|
case Event.UiCmdStop:
|
|
if (simultWithEvacuationCount > 0) CloseIPerlCommForm();
|
|
goto stop;
|
|
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();
|
|
goto stop;
|
|
}
|
|
|
|
completed = (modelessDlg as GenericDevices.IHasCompleted).Completed;
|
|
}
|
|
while (!completed);
|
|
}
|
|
|
|
modelessDlg = null;
|
|
}
|
|
|
|
benchFilled = false;
|
|
Bridge.Bench2UI(ButtonsEtc.ShowBenchEmpty);
|
|
|
|
|
|
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();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// MakeSelection() call context
|
|
/// </summary>
|
|
enum MKSelContext
|
|
{
|
|
ProcedureNotSelected,
|
|
InsideProcedure,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return values of MakeSelection()
|
|
/// </summary>
|
|
public enum Selection
|
|
{
|
|
PurgeBegin,
|
|
PurgeEnd,
|
|
Break,
|
|
Cycle,
|
|
RestOfCycle,
|
|
Test,
|
|
Q1,
|
|
Q2,
|
|
Q3,
|
|
SaveResults,
|
|
RestoreBatch,
|
|
Custom,
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Idle loop to make a procedure or test selection.
|
|
/// Handles tank emptying, camera test.
|
|
/// </summary>
|
|
/// <param name="context">Context where MakeSelection() is called</param>
|
|
/// <returns>
|
|
/// Selection.PurgeBegin
|
|
/// Selection.PurgeEnd
|
|
/// Selection.Break
|
|
/// Selection.Cycle
|
|
/// Selection.Test
|
|
/// Selection.Q1
|
|
/// Selection.Q2
|
|
/// Selection.Q3
|
|
/// Selection.SaveResults
|
|
/// </returns>
|
|
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<Event> e;
|
|
|
|
while (true)
|
|
{
|
|
/// Display an appropriate activity message
|
|
if (draining1 || draining2 || draining3)
|
|
{
|
|
Bridge.OnActivity(this, Strings.Emptying_tank);
|
|
}
|
|
else if (context == MKSelContext.ProcedureNotSelected)
|
|
{
|
|
Bridge.OnActivity(this, Strings.Please_select_a_procedure);
|
|
}
|
|
else if (context == MKSelContext.InsideProcedure)
|
|
{
|
|
Bridge.OnActivity(this, Strings.Please_select_a_cycle_a_test_or_empty);
|
|
}
|
|
|
|
/// Enable appropriate UI controls and buttons
|
|
Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
|
|
ButtonsEtc.TestCmbBoxEn |
|
|
ButtonsEtc.StopBtnEn |
|
|
((draining1 || draining2 || draining3) ? 0 :
|
|
(ButtonsEtc.StartCycleBtnEn |
|
|
ButtonsEtc.StartTestBtnsEn |
|
|
ButtonsEtc.PurgeBeginBtnEn |
|
|
((context == MKSelContext.InsideProcedure) ? ButtonsEtc.PurgeEndBtnEn : 0) |
|
|
ButtonsEtc.SensitivityTestBtnEn |
|
|
((Cameras.Count > 0) ? ButtonsEtc.CalibrationBtnEn : 0) |
|
|
ButtonsEtc.Break)) |
|
|
(((StateMachine.Scale1 != null) && (StateMachine.DrainValve1 != null) && !draining1) ? ButtonsEtc.DrainTankBtn1En : 0) |
|
|
(((StateMachine.Scale2 != null) && (StateMachine.DrainValve2 != null) && !draining2) ? ButtonsEtc.DrainTankBtn2En : 0) |
|
|
(((StateMachine.Scale3 != null) && (StateMachine.DrainValve3 != null) && !draining3) ? ButtonsEtc.DrainTankBtn3En : 0));
|
|
|
|
|
|
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 (e.Contains(Event.UiCmdStop)) break;
|
|
if (e.Contains(Event.UiCmdDrainTank1)) break;
|
|
if (e.Contains(Event.UiCmdDrainTank2)) break;
|
|
if (e.Contains(Event.UiCmdDrainTank3)) 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 if (e.Contains(Event.UiCmdStop))
|
|
{
|
|
if (draining1 || draining2 || draining3)
|
|
{
|
|
IList<IValve> valvesClose = new List<IValve>();
|
|
if (draining1) valvesClose.Add(StateMachine.DrainValve1);
|
|
if (draining2) valvesClose.Add(StateMachine.DrainValve2);
|
|
if (draining3) valvesClose.Add(StateMachine.DrainValve3);
|
|
|
|
State.Create("MainSeq : Close emptying valve(s)")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, valvesClose))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
draining1 = draining2 = draining3 = false;
|
|
}
|
|
}
|
|
else if (e.Contains(Event.UiCmdDrainTank1) && !draining1)
|
|
{
|
|
draining1 = true;
|
|
///--------------------------------------------
|
|
Bridge.OnActivity(this, Strings.Emptying_tank);
|
|
///--------------------------------------------
|
|
Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
|
|
ButtonsEtc.TestCmbBoxEn | ButtonsEtc.StopBtnEn |
|
|
(draining2 ? 0 : ButtonsEtc.DrainTankBtn2En) |
|
|
(draining3 ? 0 : ButtonsEtc.DrainTankBtn3En));
|
|
State.Create("MainSeq : Open tank 1")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DrainValve1, null))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
}
|
|
else if (e.Contains(Event.UiCmdDrainTank2) && !draining2)
|
|
{
|
|
draining2 = true;
|
|
///--------------------------------------------
|
|
Bridge.OnActivity(this, Strings.Emptying_tank);
|
|
///--------------------------------------------
|
|
Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
|
|
ButtonsEtc.TestCmbBoxEn | ButtonsEtc.StopBtnEn |
|
|
(draining1 ? 0 : ButtonsEtc.DrainTankBtn1En) |
|
|
(draining3 ? 0 : ButtonsEtc.DrainTankBtn3En));
|
|
State.Create("MainSeq : Open tank 2")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DrainValve2, null))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
}
|
|
else if (e.Contains(Event.UiCmdDrainTank3) && !draining3)
|
|
{
|
|
draining3 = true;
|
|
///--------------------------------------------
|
|
Bridge.OnActivity(this, Strings.Emptying_tank);
|
|
///--------------------------------------------
|
|
Bridge.Bench2UI(((context == MKSelContext.ProcedureNotSelected) ? ButtonsEtc.ProcedureCmbBoxEn : 0) |
|
|
ButtonsEtc.TestCmbBoxEn | ButtonsEtc.StopBtnEn |
|
|
(draining1 ? 0 : ButtonsEtc.DrainTankBtn1En) |
|
|
(draining2 ? 0 : ButtonsEtc.DrainTankBtn2En));
|
|
State.Create("MainSeq : Open tank 3")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DrainValve3, null))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
}
|
|
else if (draining1 && StateMachine.Scale1.IsEmpty(mass1.Val))
|
|
{
|
|
State.Create("MainSeq : Close tank 1")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, StateMachine.DrainValve1))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
draining1 = false;
|
|
}
|
|
else if (draining2 && StateMachine.Scale2.IsEmpty(mass2.Val))
|
|
{
|
|
State.Create("MainSeq : Close tank 2")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, StateMachine.DrainValve2))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
draining2 = false;
|
|
}
|
|
else if (draining3 && StateMachine.Scale3.IsEmpty(mass3.Val))
|
|
{
|
|
State.Create("MainSeq : Close tank 3")
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, StateMachine.DrainValve3))
|
|
.EnterState();
|
|
do { e = StateMachine.WaitRunDevsRunOps(); }
|
|
while (!e.Contains(Event.ValvesSet));
|
|
draining3 = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Create a new empty batch results from the procedure
|
|
/// </summary>
|
|
/// <param name="newBatchNr">New batch number</param>
|
|
/// <param name="procedure">Selected procedure</param>
|
|
/// <returns>Created BatchResults</returns>
|
|
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;
|
|
|
|
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,
|
|
};
|
|
|
|
if (compound)
|
|
{
|
|
int auxIx = 2 * wmNr + 1;
|
|
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.iPerl.WaterMeter iPerl = WaterMeters[wmNr] as BenchControl.WaterMeters.iPerl.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);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Reload batch results from Results database given the batch number
|
|
/// </summary>
|
|
/// <param name="oriBatchNr">Original batch number</param>
|
|
/// <param name="newBatchNr">New unique batch number</param>
|
|
/// <param name="procedure">Reloaded procedure</param>
|
|
/// <returns></returns>
|
|
Results.BatchResults RestoreBatchResults(int oriBatchNr, int newBatchNr, Procedure procedure)
|
|
{
|
|
return Results.BatchResults.FromBatch(Results.DB.LoadBatch(oriBatchNr));
|
|
}
|
|
|
|
|
|
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++;
|
|
}
|
|
}
|
|
}
|
|
}
|