diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Compound/Component.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Compound/Component.cs new file mode 100644 index 000000000..7a78b8390 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Compound/Component.cs @@ -0,0 +1,39 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System.Collections.Generic; +using Common; +using Config.Entities; +using log4net; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Compound +{ + public class Component : ComponentBase, GenericDevices.ITestMethod + { + private static readonly ILog log = LogManager.GetLogger(typeof(Component)); + public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); } + + public bool CanTest(MetersKind meters) { return meters == MetersKind.Combined; } + public bool DoTransitions() { return true; } + public bool CheckDeviceCaps(Test test, OutputPath devices, out string message) + { + return StandingStartMassCollection.StandingStartMassCollectionSeq.CheckDeviceCaps(test, devices, out message); + } + + public Component() { } + /// + public Component(Generic.IComponentCfg cfg) + : base(cfg) + { + log.Warn(this.ToString()); + } + /// + public override void Initialize() { } + + public IList Execute(Test test, int repetNr, bool isLastRepetition) + { + return (new StandingStartMassCollection.StandingStartMassCollectionSeq()).Execute(test, repetNr, isLastRepetition, true, null, DebugLevel); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Compound/Factory.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Compound/Factory.cs new file mode 100644 index 000000000..6b36e4e39 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Compound/Factory.cs @@ -0,0 +1,27 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System.Collections.Generic; +using TBF.Rig.Configs.NameOnly; +using TBF.Rig.Generic; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Compound +{ + public class Factory : IComponentFactory + { + public string ClassName { get { return this.GetType().Namespace.Substring(8); } } + public override string ToString() { return ClassName; } + + public IComponent DummyComponent() { return new StandingStartMassCollection.Compound.Component(); } + + public IComponent GetComponent(IComponentCfg cfg, IList components) { return new StandingStartMassCollection.Compound.Component(cfg); } + + public IComponentCfg DefaultConfig() { return new TestMethodCfg(this.GetType().Namespace.Substring(20), this); } + + public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component) + { + return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/Component.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/Component.cs new file mode 100644 index 000000000..0c38aec23 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/Component.cs @@ -0,0 +1,43 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System.Collections.Generic; +using Common; +using Config.Entities; +using log4net; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters +{ + public class Component : ComponentBase, GenericDevices.ITestMethod + { + private static readonly ILog log = LogManager.GetLogger(typeof(Component)); + public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); } + + public bool CanTest(MetersKind meters) { return meters == MetersKind.HeatMeter; } + public bool DoTransitions() { return true; } + public bool CheckDeviceCaps(Test test, OutputPath devices, out string message) + { + return StandingStartMassCollection.StandingStartMassCollectionSeq.CheckDeviceCaps(test, devices, out message); + } + + + readonly TestMethodCfg testMethodCfg; + + public Component() { } + /// + public Component(Generic.IComponentCfg cfg) + : base(cfg) + { + testMethodCfg = cfg as TestMethodCfg; + log.Warn(this.ToString()); + } + /// + public override void Initialize() { } + + public IList Execute(Test test, int repetNr, bool isLastRepetition) + { + return (new StandingStartMassCollectionPoseidon.StandingStartMassCollectionPoseidonSeq()).Execute(test, repetNr, isLastRepetition, false, testMethodCfg.TestParams, DebugLevel); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/Factory.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/Factory.cs new file mode 100644 index 000000000..7aa2c6681 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/Factory.cs @@ -0,0 +1,26 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System.Collections.Generic; +using TBF.Rig.Generic; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters +{ + public class Factory : IComponentFactory + { + public string ClassName { get { return this.GetType().Namespace.Substring(8); } } + public override string ToString() { return ClassName; } + + public IComponent DummyComponent() { return new StandingStartMassCollection.HeatMeters.Component(); } + + public IComponent GetComponent(IComponentCfg cfg, IList components) { return new StandingStartMassCollection.HeatMeters.Component(cfg); } + + public IComponentCfg DefaultConfig() { return new TestMethodCfg(this.GetType().Namespace.Substring(20), this); } + + public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component) + { + return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfg.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfg.cs new file mode 100644 index 000000000..81ade7298 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfg.cs @@ -0,0 +1,49 @@ +/// +/// Copyright (c) 2013-2016 Sensus Metering Systems +/// + +using System.Collections.Generic; +using System.Xml.Serialization; +using Common; +using Config.Entities; +using TBF.Rig.Generic; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters +{ + public class TestMethodCfg : ComponentCfgBase, Generic.IComponentCfg + { + public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestMethodCfg) })[0]; + public override XmlSerializer GetSerializer() { return Serializer; } + + public IComponentCfgCtrl GetControl(IList cmpntEntities) { return new TestMethodCfgCtrl(); } + + /// Test parameters + [XmlIgnore] + public TestParams TestParams; + public override IParamsProvider GetRuntimeTestParamsProvider() { return TestParams; } + public override IParamsProvider CreateTestParamsProvider() { return new TestParams(true); } + public override IParamsProvider GetUITestParamsProvider(Test test) + { + return (test.Method == Name) ? base.GetUITestParamsProvider(test) : null; + } + + /// Private parameterless constructor invoked by all other (public) constructors + TestMethodCfg() + { + TestParams = new TestParams(true); + } + + public TestMethodCfg(string name, IComponentFactory factory) + : this() + { + Name = name; + Factory = factory; + ParentName = string.Empty; + } + + public string ToString(int i) + { + return string.Format("Name={0}", Name); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.cs new file mode 100644 index 000000000..f70b7bb6c --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.cs @@ -0,0 +1,70 @@ +/// +/// Copyright (c) 2013-2016 Sensus Metering Systems +/// + +using System; +using System.Windows.Forms; +using Common; +using TBF.Rig.Generic; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters +{ + public partial class TestMethodCfgCtrl : UserControl, IComponentCfgCtrl + { + public bool ShowMore { get { return false; } } + + StandingStartMassCollection.HeatMeters.TestMethodCfg config; + public IComponentCfg Config + { + get { return config as IComponentCfg; } + set + { + config = value as StandingStartMassCollection.HeatMeters.TestMethodCfg; + Redraw(); + } + } + + public TestMethodCfgCtrl() + { + InitializeComponent(); + } + + private void EntryFormCfgCtrl_Load(object sender, EventArgs e) + { + Redraw(); + } + + public void Closing() + { + } + + void Redraw() + { + if (config == null) return; /// Control was not loaded, settings were not changed + classNameLabel.Text = config.Factory.ClassName; + nameTextBox.Text = config.Name; + } + + public void Unlock() + { + nameTextBox.Enabled = true; + } + + public CfgUpdateFlags VerifyCfg(ref string message) + { + CfgUpdateFlags flags = CfgUpdateFlags.None; + return flags; + } + + public CfgUpdateFlags UpdateCfg() + { + CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd; + + if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed + + config.Name = nameTextBox.Text; + + return flags; + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.designer.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.designer.cs new file mode 100644 index 000000000..7772226c4 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.designer.cs @@ -0,0 +1,86 @@ +/// +/// Copyright (c) 2013-2016 Sensus Metering Systems +/// +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters +{ + partial class TestMethodCfgCtrl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.nameTextBox = new System.Windows.Forms.TextBox(); + this.nameLabel = new System.Windows.Forms.Label(); + this.classNameLabel = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // nameTextBox + // + this.nameTextBox.Enabled = false; + this.nameTextBox.Location = new System.Drawing.Point(137, 57); + this.nameTextBox.Name = "nameTextBox"; + this.nameTextBox.Size = new System.Drawing.Size(130, 20); + this.nameTextBox.TabIndex = 5; + // + // nameLabel + // + this.nameLabel.AutoSize = true; + this.nameLabel.Location = new System.Drawing.Point(27, 60); + this.nameLabel.Name = "nameLabel"; + this.nameLabel.Size = new System.Drawing.Size(35, 13); + this.nameLabel.TabIndex = 4; + this.nameLabel.Text = "Name"; + // + // classNameLabel + // + this.classNameLabel.AutoSize = true; + this.classNameLabel.Location = new System.Drawing.Point(134, 33); + this.classNameLabel.Name = "classNameLabel"; + this.classNameLabel.Size = new System.Drawing.Size(83, 13); + this.classNameLabel.TabIndex = 3; + this.classNameLabel.Text = "ComonentName"; + // + // BasicPrinterCfgCtrl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.nameTextBox); + this.Controls.Add(this.nameLabel); + this.Controls.Add(this.classNameLabel); + this.Name = "BasicPrinterCfgCtrl"; + this.Size = new System.Drawing.Size(300, 200); + this.Load += new System.EventHandler(this.EntryFormCfgCtrl_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox nameTextBox; + private System.Windows.Forms.Label nameLabel; + private System.Windows.Forms.Label classNameLabel; + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.resx b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestMethodCfgCtrl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestParams.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestParams.cs new file mode 100644 index 000000000..e337f5a14 --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/HeatMeters/TestParams.cs @@ -0,0 +1,197 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System.IO; +using System.Xml.Serialization; +using Common; +using Config.Entities; +using TBF.Resources; +using TBF.Rig.Generic; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters +{ + public class TestParams : TestParamsBase, IParamsProvider, ITestParams + { + public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestParams) })[0]; + public override XmlSerializer GetSerializer() { return Serializer; } + + public float ErrorLimitLo; /// [%] + public float ErrorLimitHi; /// [%] + public bool EvaluateVolume; /// true = evaluate also the volume, false = evaluate only energy + public float TempWarmLo; /// Low limit for warm temperature [°C] + public float TempWarmHi; /// High limit for warm temperature [°C] + public float TempColdLo; /// Low limit for cold temperature [°C] + public float TempColdHi; /// High limit for cold temperature [°C] + public bool FlowMeasuredAtHiTempPipe; /// true = flow measured at high temp. pipe, false = flow measured at low temp. pipe + public float DeltaTempWarm; + public float DeltaTempCold; + public float ChangeInTimeWarm; + public float ChangeInTimeCold; + public string Prompt; + + public override void InitializeAll() + { + FlowMeasuredAtHiTempPipe = false; + } + + + string[] paramNames = new string[] + { + Strings.Err_limit_neg_pct_chdr, + Strings.Err_limit_pos_pct_chdr, + Strings.Evaluate_volume, + "T hi min", + "T hi max", + "T lo min", + "T lo max", + "Flow measured at high temp.pipe", + "Delta T warm", + "Delta T cold", + "Change in time T warm", + "Change in time T cold", + Strings.Prompt, + }; + public override string ParamName(int i) { return paramNames[i]; } + public override int ParamsCount() { return paramNames.Length; } + + public override string ToString(int i) + { + switch (i) + { + case 0: return ErrorLimitLo.ToString(); + case 1: return ErrorLimitHi.ToString(); + case 2: return (EvaluateVolume ? Strings.yes : Strings.no); + case 3: return TempWarmLo.ToString(); + case 4: return TempWarmHi.ToString(); + case 5: return TempColdLo.ToString(); + case 6: return TempColdHi.ToString(); + case 7: return (FlowMeasuredAtHiTempPipe ? Strings.yes : Strings.no); + case 8: return DeltaTempWarm.ToString(); + case 9: return DeltaTempCold.ToString(); + case 10: return ChangeInTimeWarm.ToString(); + case 11: return ChangeInTimeCold.ToString(); + case 12: return Prompt; + default: return string.Empty; + } + } + + public CfgUpdateFlags UpdateParam(int i, string strValue) + { + switch (i) + { + case 0: ErrorLimitLo = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None; + case 1: ErrorLimitHi = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None; + case 2: EvaluateVolume = strValue.Equals(Strings.yes); return CfgUpdateFlags.None; + case 3: TempWarmLo = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None; + case 4: TempWarmHi = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None; + case 5: TempColdLo = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None; + case 6: TempColdHi = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None; + case 7: FlowMeasuredAtHiTempPipe = strValue.Equals(Strings.yes); return CfgUpdateFlags.None; + case 8: DeltaTempWarm = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None; + case 9: DeltaTempCold = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None; + case 10: ChangeInTimeWarm = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None; + case 11: ChangeInTimeCold = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None; + case 12: Prompt = strValue; return CfgUpdateFlags.None; + default: return CfgUpdateFlags.None; + } + } + + public bool ValidateParam(int i, string strValue, out string message) + { + message = string.Empty; + float dummy; + + switch (i) + { + case 0: + case 1: + case 3: + case 4: + case 5: + case 6: + if (Utils.TryParseSFloat(strValue, out dummy)) return true; + break; + case 2: + case 7: + if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true; + break; + case 8: + case 9: + case 10: + case 11: + if (Utils.TryParseUFloat(strValue, out dummy)) return true; + break; + case 12: + return true; + default: + message = "Invalid index"; + return false; + } + + message = ParamName(i) + " is invalid"; + return false; + } + + void CopyContentTo(TestParams prms) + { + prms.ErrorLimitLo = ErrorLimitLo; + prms.ErrorLimitHi = ErrorLimitHi; + prms.EvaluateVolume = EvaluateVolume; + prms.TempWarmLo = TempWarmLo; + prms.TempWarmHi = TempWarmHi; + prms.TempColdLo = TempColdLo; + prms.TempColdHi = TempColdHi; + prms.FlowMeasuredAtHiTempPipe = FlowMeasuredAtHiTempPipe; + prms.DeltaTempWarm = DeltaTempWarm; + prms.DeltaTempCold = DeltaTempCold; + prms.ChangeInTimeWarm = ChangeInTimeWarm; + prms.ChangeInTimeCold = ChangeInTimeCold; + prms.Prompt = Prompt; + } + + public IParamsProvider Clone() + { + TestParams pars = new TestParams(); + CopyContentTo(pars); + return pars; + } + + public override void UpdateFromDbEntity(ComponentTest dbEntity) + { + if (dbEntity == null) return; + try + { + TestParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as TestParams; + + testParamsEntity = dbEntity; + componentName = dbEntity.CmpntName; + test = dbEntity.Test; + + if (tmp != null) tmp.CopyContentTo(this); + } + catch + { + } + } + + /// + /// Parameterless constructor initializes the parameters + /// + public TestParams() + { + } + + public TestParams(bool initialize) + { + if (initialize) InitializeAll(); + } + + public TestParams(ComponentTest testParamsEntity, string componentName, Test test) + { + this.testParamsEntity = testParamsEntity; + this.componentName = componentName; + this.test = test; + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Single/Component.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Single/Component.cs new file mode 100644 index 000000000..b7c86676b --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Single/Component.cs @@ -0,0 +1,39 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System.Collections.Generic; +using Common; +using Config.Entities; +using log4net; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Single +{ + public class Component : ComponentBase, GenericDevices.ITestMethod + { + private static readonly ILog log = LogManager.GetLogger(typeof(Component)); + public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); } + + public bool CanTest(MetersKind meters) { return meters == MetersKind.Single; } + public bool DoTransitions() { return true; } + public bool CheckDeviceCaps(Test test, OutputPath devices, out string message) + { + return StandingStartMassCollection.StandingStartMassCollectionSeq.CheckDeviceCaps(test, devices, out message); + } + + public Component() { } + /// + public Component(Generic.IComponentCfg cfg) + : base(cfg) + { + log.Warn(this.ToString()); + } + /// + public override void Initialize() { } + + public IList Execute(Test test, int repetNr, bool isLastRepetition) + { + return (new StandingStartMassCollection.StandingStartMassCollectionSeq()).Execute(test, repetNr, isLastRepetition, false, null, DebugLevel); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Single/Factory.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Single/Factory.cs new file mode 100644 index 000000000..1780905dd --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/Single/Factory.cs @@ -0,0 +1,27 @@ +/// +/// Copyright (c) 2013-2016 Sensus Metering Systems +/// + +using System.Collections.Generic; +using TBF.Rig.Configs.NameOnly; +using TBF.Rig.Generic; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Single +{ + public class Factory : IComponentFactory + { + public string ClassName { get { return this.GetType().Namespace.Substring(8); } } + public override string ToString() { return ClassName; } + + public IComponent DummyComponent() { return new StandingStartMassCollection.Single.Component(); } + + public IComponent GetComponent(IComponentCfg cfg, IList components) { return new StandingStartMassCollection.Single.Component(cfg); } + + public IComponentCfg DefaultConfig() { return new TestMethodCfg(this.GetType().Namespace.Substring(20).Replace(".Single", ""), this); } + + public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component) + { + return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this); + } + } +} diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/StandingStartMassCollectionPoseidonSeq.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/StandingStartMassCollectionPoseidonSeq.cs new file mode 100644 index 000000000..7f11ae0cb --- /dev/null +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionPoseidon/StandingStartMassCollectionPoseidonSeq.cs @@ -0,0 +1,1262 @@ +/// +/// Copyright (c) 2013-2021 Sensus Slovensko a.s. +/// + +using System; +using System.Collections.Generic; +using System.IO; +using Common; +using Config.Entities; +using log4net; +using TBF.Boxes; +using TBF.Resources; +using TBF.Rig.GenericDevices; +using TBF.UiBridge; + +namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon +{ + public class StandingStartMassCollectionPoseidonSeq : Sequences.SequenceBase + { + private static readonly ILog log = LogManager.GetLogger(typeof(StandingStartMassCollectionPoseidonSeq)); + + /// + /// Check capabilities of devces in the output path required for this test method + /// + /// Devices + /// true when capabilities of devices are OK + public static bool CheckDeviceCaps(Config.Entities.Test test, OutputPath devices, out string message) + { + if (!(StateMachine.ControlBoardMain is ControlBoard.Papouch.PapouchCB) && + !(StateMachine.ControlBoardMain is ControlBoard.Uni.UniCB)) + { + /// Control board does not support this method + message = string.Format("{0}: {1}", test.Name, Strings.Test_bench_does_not_suport_selected_test_method); + return false; + } + + if (!(devices.Scale is IScale)) + { + /// Scale is missing + message = string.Format("{0}: {1}", test.Name, Strings.Missing_a_scale); + return false; + } + + if (test.Volume > devices.Scale.Capacity * Constants.TankFullFactor) + { + /// Scale capacity is not sufficient + message = string.Format("{0}: {1}", test.Name, Strings.Test_volume_exceeds_the_scale_capacity); + return false; + } + + if (!(devices.Diverter is IDiverter)) + { + /// Diverter is missing + message = string.Format("{0}: {1}", test.Name, Strings.Missing_a_diverter); + return false; + } + + if (!(devices.FlowMeter is IFlowMeter)) + { + /// Flow meter is missing + message = string.Format("{0}: {1}", test.Name, Strings.Missing_a_flow_meter); + return false; + } + + if (!(devices.RegValve is GenericDevices.IRegValve)) + { + /// Regulation valve is missing + message = string.Format("{0}: {1}", test.Name, Strings.Missing_a_regulation_valve); + return false; + } + + message = string.Empty; + return true; + } + + /// + /// Fixed start mass collection method sequence + /// + /// Test entity + /// + /// Event.Done . . . . . . . OK + /// Event.MakeSecondPass . . OK, 2nd pass (=evaluation) required + /// Event.UiCmdStop . . . . Stopped by the user using the on-screen button STOP + /// Event.OpArgumentError . Target flow is out of range + /// Event.Error . . . . . . Unspecified error + /// + public IList Execute(Config.Entities.Test test, int repetitionNr, bool isLastRepetition, + bool compound, + HeatMeters.TestParams heatMetersTestParams, + Common.DebugMode debugLevel) + { + ControlBoard.IControlBoard cBrd = StateMachine.ControlBoardMain; + IScale scale = cBrd.Devices.Scale as IScale; + + if ((outPath.FlowMeter is IFlowMeterSingle) && + (outPath.FlowMeter as IFlowMeterSingle).GetRange(test.TempLimLo, test.TempLimHi) == -1) + { + Bridge.OnError(this, Strings.Flow_meter_temperature_range_does_not_fit_this_test_conditions); + return new List { Event.ConfigurationError }; /// or Event.UiCmdStop ??? + } + + IList e; /// Events from currently running operations + int waterMetersCount = Math.Min(BenchInfo.WaterMetersCount, sensPath.RegisterReaders.Length); + DateTimeBox timeStampStart = new DateTimeBox(); + DateTimeBox timeStampEnd = new DateTimeBox(); + FloatBox startSwitchTime = new FloatBox(); + FloatBox stopSwitchTime = new FloatBox(); + int tMass1 = 0; + int tMass2 = 0; + checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state + processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null); + + if (cBrd is ControlBoard.Uni.UniCB) + { + int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; + if (sensPath != null && sensPath.RegisterReaders != null) + { + foreach (var rr in sensPath.RegisterReaders) + { + IRegReaderPulses rrPls = rr as IRegReaderPulses; + if (rrPls != null && rrPls.Position >= 1 && rrPls.Position <= 8) + { + filters[rrPls.Position - 1] = rrPls.Filter; + } + } + } + (cBrd as ControlBoard.Uni.UniCB).SetFiltersPidShortPulses(filters, outPath.PidCoef, test.ShortPulses); + } + + IList readTempPressOps = new List(); + if (benchPath.TempMtrUp != null) readTempPressOps.Add(benchPath.TempMtrUp.ReadTempOp(ref TempUp)); + if (benchPath.TempMtrDown != null) readTempPressOps.Add(benchPath.TempMtrDown.ReadTempOp(ref TempDown)); + if (outPath.TempMtrDiv != null) readTempPressOps.Add(outPath.TempMtrDiv.ReadTempOp(ref TempDiv)); + if (benchPath.PressMtrUp != null) readTempPressOps.Add(benchPath.PressMtrUp.ReadPressureOp(ref PressUp)); + if (benchPath.PressMtrDown != null) readTempPressOps.Add(benchPath.PressMtrDown.ReadPressureOp(ref PressDown)); + if (benchPath.PressMtrDelta != null) readTempPressOps.Add(benchPath.PressMtrDelta.ReadPressureOp(ref PressDelta)); + if (benchPath.ElectricMtrUp != null) readTempPressOps.Add(benchPath.ElectricMtrUp.ReadPressureOp(ref ElectricUp)); + if (benchPath.ElectricMtrDown != null) readTempPressOps.Add(benchPath.ElectricMtrDown.ReadPressureOp(ref ElectricDown)); + if (benchPath.ElectricMtrDelta != null) readTempPressOps.Add(benchPath.ElectricMtrDelta.ReadPressureOp(ref ElectricDelta)); + if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefWarm1.ReadTempOp(ref TempRefHi1)); + if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefWarm2.ReadTempOp(ref TempRefHi2)); + if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefCold1.ReadTempOp(ref TempRefLo1)); + if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefCold2.ReadTempOp(ref TempRefLo2)); + + Event retVal = Event.Done; + + int totalPulses = Convert.ToInt32(test.Volume / outPath.FlowMeter.LtrPerPulse); + + ///============================================================================================ + + /// Read pressure and temperature once before calling Bridge.OnTestSelected(...) + State.Create(string.Format("{0}({1}) : Measuring process data", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (e.Contains(Event.Busy)); + + /// Start the test, initialize test results + Bridge.OnTestSelected(this, new TestSelectedEventArgs(test, repetitionNr, inPath, benchPath, outPath, sensPath, heatMetersPath)); + string testName = Results.Utils.GetTestName(test.Name, test.Repeats, repetitionNr); + log.DebugFormat("Start the test - testName: {0}, test -> name: {1} -> Repeats: {2} -> repetitionNr: {3}", testName, test.Name, test.Repeats, repetitionNr); + + /// + /// Optionally display prompt to emerge temperature meters to appropriate baths for heat meters test + /// + IOperation heatMetersPromptOp = null; + if (heatMetersTestParams != null && !string.IsNullOrEmpty(heatMetersTestParams.Prompt)) + { + /// Make sure the CycleBeginForm is closed + if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stopTest; + + heatMetersPromptOp = new Operations.MessageBoxOp(heatMetersTestParams.Prompt); + } + + + if (test.DoDraining || (scale.Mass + test.Volume >= scale.Capacity * Constants.TankFullFactor)) + { + /// + /// There is not enough room in the tank OR unconditional draining ... drain the water tank + /// + IList ops = new List(readTempPressOps); + ops.Add(heatMetersPromptOp); + switch (DrainTheTank(scale, ops)) + { + case Event.Error: { retVal = Event.Error; goto stopTest; } + case Event.UiCmdStop: { retVal = Event.UiCmdStop; goto stopTest; } + } + } + /// + /// Make sure the drain valve is closed + /// + State.Create(string.Format("{0}({1}) : Make sure the drain valve is closed", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(heatMetersPromptOp) + .AddOperation(cBrd.SetValvesOp(null, scale.DrainValve)) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.JustStarted)); + + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (!e.Contains(Event.ValvesSet)); + + + //------------------------------------------------ + Bridge.OnActivity(this, Strings.Starting_the_pump); + //------------------------------------------------ + + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + int flowSetTime0 = StateMachine.Time; + + if (inPath.Pump is GenericDevices.IPumpFM) (inPath.Pump as GenericDevices.IPumpFM).TurnOn(test.PumpPower); + /// + State.Create(string.Format("{0}({1}) : Starting the pump", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + //.AddOperation(new Operations.SetAllRegulValvesOp(inPath.RegulValves, inPath.RegulValvesPct, 60)) + .AddOperation(heatMetersPromptOp) + .AddOperation(inPath.Pump != null ? cBrd.SetValvesOp(inPath.Pump, null) : null) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + } + while (e.Contains(Event.ValvesBusy) /* || !e.Contains(Event.AllPositionsReached)*/); + + + if (test.TimePump2StartV > 0) + { + State.Create(string.Format("{0}({1}) : Waiting after the pump started", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(new Operations.TimerOp(test.TimePump2StartV)) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (!e.Contains(Event.TimerExpired)); + } + + + if (benchPath.StopBFValve != null) + { + State.Create(string.Format("{0}({1}) : Opening the stop backflow valve", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(cBrd.SetValvesOp(benchPath.StopBFValve, null)) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + } + while (!e.Contains(Event.ValvesSet)); + } + + + if (test.TimeBeforeFlow > 0) + { + State.Create(string.Format("{0}({1}) : Waiting before flow setting process starts", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(new Operations.TimerOp(test.TimeBeforeFlow)) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (!e.Contains(Event.TimerExpired)); + } + + //------------------------------------------------ + Bridge.OnActivity(this, Strings.Setting_the_flow); + //------------------------------------------------ + if (inPath.Pump is GenericDevices.IPumpFM) + { + (inPath.Pump as GenericDevices.IPumpFM).TurnOn(test.PumpPower); + } + /// + State.Create(string.Format("{0}({1}) : Pump on", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(cBrd.SetValvesOp(inPath.Pump, null)) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (e.Contains(Event.ValvesBusy)); + /// + State.Create(string.Format("{0}({1}) : Start valve open", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(cBrd.OpenStartValveOp()) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (e.Contains(Event.ValvesBusy)); + /// + State.Create(string.Format("{0}({1}) : Setting the flow", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec)) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting)); + + if (e.Contains(Event.OpArgumentError)) { retVal = Event.OpArgumentError; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.RegulValveTimeOut)) + { + Bridge.OnError(this, Strings.Flow_adjustment_failed); + retVal = Event.RecoverableError; + goto stopTest; + } + if (e.Contains(Event.Next)) + { + break; /// Simulate flow is within range + } + } + while (!e.Contains(Event.FlowReached)); + + /// + /// Flow is withing required range at this point + /// + int flowSetTime = StateMachine.Time - flowSetTime0; + + if (heatMetersTestParams != null && heatMetersPath != null) + { + //--------------------------------------------------- + Bridge.OnActivity(this, Strings.Setting_temperature); + //--------------------------------------------------- + + int lastTimeSec = StateMachine.Time; + double Tw_last = 0; + double Tc_last = 0; + + State.Create(string.Format("{0}({1}) : Checking if the temperature is stable", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(heatMetersPromptOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.Next)) + { + break; /// Simulate temperature is within range + } + + if (TempRefHi1.Val != 0 && TempRefHi2.Val != 0 && TempRefLo1.Val != 0 && TempRefLo2.Val != 0) + { + if (StateMachine.Time - lastTimeSec > 10 || StateMachine.Time - lastTimeSec < 0) + { + double Tw = (TempRefHi1.Val + TempRefHi2.Val) / 2; + double Tc = (TempRefLo1.Val + TempRefLo2.Val) / 2; + if ((heatMetersTestParams.TempWarmLo <= Tw) && (Tw <= heatMetersTestParams.TempWarmHi) && + (heatMetersTestParams.TempColdLo <= Tc) && (Tc <= heatMetersTestParams.TempColdHi) && + (Math.Abs(Tw - Tw_last) <= heatMetersTestParams.ChangeInTimeWarm) && + (Math.Abs(Tc - Tc_last) <= heatMetersTestParams.ChangeInTimeCold) && + (Math.Abs(TempRefHi1.Val - TempRefHi2.Val) <= heatMetersTestParams.DeltaTempWarm) && + (Math.Abs(TempRefLo1.Val - TempRefLo2.Val) <= heatMetersTestParams.DeltaTempCold)) + { + break; /// Temperature is withing required range + } + + lastTimeSec = StateMachine.Time; + Tw_last = Tw; + Tc_last = Tc; + } + } + } + while (true); + } + else if (!string.IsNullOrEmpty(test.TempControl) && benchPath.TempMtrUp != null && benchPath.TempMtrDown != null) + { + //--------------------------------------------------- + Bridge.OnActivity(this, Strings.Setting_temperature); + //--------------------------------------------------- + + State.Create(string.Format("{0}({1}) : Wait until the water temperature is within limits", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.Next)) + { + break; /// Simulate temperature is within range + } + + if (TempUp.Val >= test.TempLimLo && TempUp.Val <= test.TempLimHi && + TempDown.Val >= test.TempLimLo && TempDown.Val <= test.TempLimHi) + { + break; /// Temperature set withing required range + } + } + while (true); + } + + /// + /// Temperature is withing required range at this point + /// + + //----------------------------------------------------------------- + Bridge.OnActivity(this, Strings.Stopping_flow_for_the_fixed_start); + //----------------------------------------------------------------- + State.Create(string.Format("{0}({1}) : Stop flow regulation", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .EnterState(); + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + + IOperation testInProgress = cBrd.StandingStartStopTestOp(test, 2 * totalPulses, Devices.Diverter is TBF.Rig.Uni.Diverter.Diverter); + IOperation controlFlowOp = cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, int.MaxValue, test.TimeBeforeFlow); + + State.Create(string.Format("{0}({1}) : Close the start/stop valve before measuring the start mass", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(cBrd.CloseStartValveOp()) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (!e.Contains(Event.ValvesSet)); + + State.Create(string.Format("{0}({1}) : Start the standing start/stop test", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress) + .EnterState(); + for (int i = 0; i < 3; i++) + { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + + int time = StateMachine.Time; + double currentFlow = RefFlow.Val; + + //------------------------------------------------ + Bridge.OnActivity(this, Strings.Measuring_the_weight); + //------------------------------------------------ + + LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name); + + if (heatMetersPath == null) LogProcessDataHeader(processDataLogger, "Start mass"); + else LogProcessDataHeaderHeatMeters(processDataLogger, "Start mass"); + + /// + /// Enter water meter begin states and read the start mass at the same time + /// + GenericDevices.IHasWMStatesForm dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IHasWMStatesForm; + IOperation readStartMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread); + + if (dataEntryCmpnt != null) + { + string fileName = string.Format("{0}-{1}-start.bmp", test.Name, repetitionNr); //string.Format("{0}-start.bmp", test.Name); + + IValve triggerValve = null; + bool triggerSend = false; + if (dataEntryCmpnt is GenericDevices.IDataEntryForCamera) + { + string[] startImages = new string[sensPath.RegisterReaders.Length]; + + State state2 = State.Create(string.Format("{0}({1}) : Grab images", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(readStartMassOp) + .AddOperation(testInProgress) + .AddOperation(processDataLoggingOp); + + for (int i = 0; i < sensPath.RegisterReaders.Length; i++) + { + GenericDevices.IRegReaderStillCamera roi = sensPath.RegisterReaders[i] as GenericDevices.IRegReaderStillCamera; + if (roi != null) + { + ///if exist valve trigger camera open + triggerValve = roi.GetValve(); + if (triggerValve != null && !triggerSend) + { + OpenValveGrabImage(cBrd,testInProgress, triggerValve, e, + string.Format("{0}({1}) : Grabbing images - valve open", test.Method, test.Name)); + triggerSend = true; + } + string directory = Path.Combine(Program.TempImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + Directory.CreateDirectory(directory); + startImages[i] = Path.Combine(directory, fileName); + state2.AddOperation(roi.GrabImageOp(startImages[i])); + } + else + { + /// Camera simulation + string directory = Path.Combine(Program.TempImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + Directory.CreateDirectory(directory); + startImages[i] = Path.Combine(directory, fileName); + } + } + state2.EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test)); + + if (e.Contains(Event.Error)) { retVal = Event.Error; break; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; break; } + } + while (e.Contains(Event.CameraBusy)); + + (dataEntryCmpnt as GenericDevices.IDataEntryForCamera).StartImages = startImages; + } + + ///valve trigger camera close + if (triggerValve != null) + { + CloseValveGrabImage(cBrd,testInProgress,triggerValve, e, + string.Format("{0}({1}) : Grabbing images - valve close", test.Method, test.Name)); + } + /////// + + + Bridge.OnActivity(this, Strings.Enter_water_meter_data); + long readStartTime = StateMachine.Time; + State.Create(string.Format("{0}({1}) : Enter start states of water meters", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(readStartMassOp) + .AddOperation(testInProgress) + .AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders)) + .AddOperation(processDataLoggingOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (!e.Contains(Event.ModelessFormClosed)); + long readEndTime = StateMachine.Time; + + log.Debug("Read poseidon - took:" + (readEndTime - readStartTime)); + + if (heatMetersTestParams != null) + { + for (int i = 0; i < TBF.Data.HeatMetersCount; i++) + { + Rig.RegisterReaders.StandingStartStop.RegisterReader volumeRegisterReader = + sensPath.RegisterReaders[2 * i] as Rig.RegisterReaders.StandingStartStop.RegisterReader; + + Rig.RegisterReaders.StandingStartStop.RegisterReader energyRegisterReader = + sensPath.RegisterReaders[2 * i + 1] as Rig.RegisterReaders.StandingStartStop.RegisterReader; + + if (volumeRegisterReader != null) volumeRegisterReader.BeginWMState = dataEntryCmpnt.WMStartState(i); + if (energyRegisterReader != null && dataEntryCmpnt is GenericDevices.IHasHeatMtrStatesForm) + { + energyRegisterReader.BeginWMState = (float)(dataEntryCmpnt as GenericDevices.IHasHeatMtrStatesForm).EnergyStartState(i); + } + } + } + else + { + for (int i = 0; i < waterMetersCount; i++) + { + IRegReader rr = sensPath.RegisterReaders[i]; + + if (rr is Rig.RegisterReaders.StandingStartStop.RegisterReader) + (rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).BeginWMState = dataEntryCmpnt.WMStartState(i); + + if (rr is Rig.Network.Camera.RoiForFixedStart.Roi) + (rr as Rig.Network.Camera.RoiForFixedStart.Roi).BeginWMState = dataEntryCmpnt.WMStartState(i); + if (rr is Rig.Network.Camera.RoiForFixedStartKeyence.Roi) + { + (rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).BeginWMState = + dataEntryCmpnt.WMStartState(i); + log.DebugFormat(" StandingStartMassCollectionSeq.cs - BeginWMState [{0}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMStartState(i)); + } + if (rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi) + (rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).BeginWMState = dataEntryCmpnt.WMStartState(i); + } + } + + if (dataEntryCmpnt is IDataEntryForCamera && (dataEntryCmpnt as IDataEntryForCamera).SaveImages) + { + log.Debug("Save images WMStartState..."); + /// SaveImages==true ... copy images to the directory that will be archived at the end of the cycle + for (int i = 0; i < sensPath.RegisterReaders.Length; i++) + { + var roi = sensPath.RegisterReaders[i] as IRegReaderStillCamera; + if (roi != null) + { + string srcDir = Path.Combine(Program.TempImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + string destDir = Path.Combine(Program.ImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + try + { + if (File.Exists(Path.Combine(srcDir, fileName))) + { + Directory.CreateDirectory(destDir); + string destFName = string.IsNullOrEmpty((dataEntryCmpnt as IDataEntryForCamera).TestStartImgName(i, testName)) + ? fileName : (dataEntryCmpnt as IDataEntryForCamera).TestStartImgName(i, testName); + File.Copy(Path.Combine(srcDir, fileName), Path.Combine(destDir, destFName), true); + log.DebugFormat("Save images sourceFile: {0}, destFile: {1} ",Path.Combine(srcDir, fileName), Path.Combine(destDir, destFName)); + } + } + catch (Exception exc) + { + log.ErrorFormat("Failed to copy image {0} to {1}: {2}", fileName, destDir, exc.Message); + } + } + } + } + } + else + { + State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress) + .AddOperation(readStartMassOp) + .AddOperation(processDataLoggingOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.ScaleTimeout)) + { + Bridge.OnError(this, Strings.Mass_measurement_timeout); + retVal = Event.RecoverableError; + goto stopTest; + } + } + while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next)); + } + /// + tMass1 = StateMachine.Time; + + + if (heatMetersPath == null) + LogProcessDataHeader(processDataLogger, "Measurement"); + else + LogProcessDataHeaderHeatMeters(processDataLogger, "Measurement"); + + //------------------------------------------------ + Bridge.OnActivity(this, Strings.Test_in_progress); + //------------------------------------------------ + + /// Measurement loop preparation + TestStartTime = DateTime.Now; + StartTime = (double)StateMachine.Time; + int estimtdEndTime = StateMachine.Time + (int)test.TestTime; + int remainingTime; + StartNewStatistics(outPath.FlowMeter, BatchRslts.Batch.BatchNr, test, repetitionNr, Math.Max((int)(test.TestTime / 10), 5)); + + int initialPulsesCount = RefPulses; + + State.Create(string.Format("{0}({1}) : Start the test, open the start/stop valve", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime)) + .AddOperation(testInProgress) + .AddOperation(controlFlowOp) + .AddOperation(processDataLoggingOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.OpArgumentError)) { retVal = Event.OpArgumentError; goto stopTest; } + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + + /// Show remaining time + if ((remainingTime = Math.Max(estimtdEndTime - StateMachine.Time, 0)) > 60) + Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Test_in_progress, remainingTime / 60, "min", remainingTime % 60, Strings.sec)); + else + Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime)); + + /// Update statistics + RefFrequency.Val = cBrd.RefFrequency; + RefFlow.Val = outPath.FlowMeter.ReadFlow(); + UpdateAllStatistics(); + + #region Heat meters + + if (heatMetersTestParams != null) + { + /// Update heatmeter volume and energy values + if (lastEnergyUpdateTime == 0) + { + lastEnergyUpdateTime = StateMachine.Time; + } + else + { + //double deltaTime = (double)(StateMachine.Time - lastEnergyUpdateTime); + double T_in = (TempRefHi1.Val + TempRefHi2.Val) / 2; /// [°C] + double T_out = (TempRefLo1.Val + TempRefLo2.Val) / 2; /// [°C] + double deltaVolume = outPath.FlowMeter.LtrPerPulse * RefPulsesDelta; /// [l] + double deltaEnergy = (0.001 * deltaVolume) * (T_in - T_out) * Formulas.HeatCoefficientWater(16, T_in, T_out, heatMetersTestParams.FlowMeasuredAtHiTempPipe); /// [J] = [m3] * [K] * [J/(m3 K)] + Energy.Update(deltaEnergy); + VolumeForEnergy.Update(deltaVolume); + lastEnergyUpdateTime = StateMachine.Time; + } + } + + #endregion + + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test)); + } + while ((cBrd.DebugLevel==DebugMode.Simulate && !e.Contains(Event.FlowReached)) || + (cBrd.DebugLevel!=DebugMode.Simulate && cBrd.RefPulses < initialPulsesCount + totalPulses && !e.Contains(Event.TestCompleted) && !e.Contains(Event.Next))); + + /// Measurement loop end + log.WarnFormat("Start valve switch time on test start = {0} ms", cBrd.ValveOpenCloseTime); + StopRecordingStatistics(); + EndTime = (double)StateMachine.Time; + TestEndTime = DateTime.Now; + + State.Create(string.Format("{0}({1}) : Closing the start/stop valve at the end of the standing start/stop test", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress) + .AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime)) + .AddOperation(processDataLoggingOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + } + while (e.Contains(Event.ValvesBusy)); + + log.WarnFormat("Start valve switch time on test end = {0} ms", cBrd.ValveOpenCloseTime); + + if (heatMetersPath == null) + LogProcessDataHeader(processDataLogger, "End mass"); + else + LogProcessDataHeaderHeatMeters(processDataLogger, "End mass"); + + //------------------------------------------------ + Bridge.OnActivity(this, Strings.Measuring_the_weight); + //------------------------------------------------ + State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress) + .AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread)) + .AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec)) + .AddOperation(processDataLoggingOp) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.ScaleTimeout)) + { + Bridge.OnError(this, Strings.Mass_measurement_timeout); + retVal = Event.RecoverableError; + goto stopTest; + } + } + while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next)); + /// + tMass2 = StateMachine.Time; + + if (test.DoDrainingAfter) + { + State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperation(cBrd.SetValvesOp(scale.DrainValve, null)) + .EnterState(); + do + { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + } + while (e.Contains(Event.ValvesBusy)); + } + + + double massStart = MeasurementCorrection.CorrectedValue(StartMass.Val, scale.Corrections); + double massEnd = MeasurementCorrection.CorrectedValue(EndMass.Val, scale.Corrections); + double densityOut = Formulas.WaterDensityFromTempPress((TempUpStat.Average + TempDownStat.Average) / 2, + (PressUpStat.Average + PressDownStat.Average) / 2); + double buoyancy = Formulas.Buoyancy(); + double massOfEvaporatedWater = (double)(tMass2 - tMass1) * outPath.Scale.EvaporationRate(TempDivStat.Average); + double volumeCTV = 1000.0 * buoyancy * (massEnd - massStart + massOfEvaporatedWater) / densityOut; + if (debugLevel == Common.DebugMode.Simulate) volumeCTV = test.Volume; + + double refEnergy = Energy.Sum * volumeCTV / VolumeForEnergy.Sum; /// [J]=[J]*[l]/[l] + + /// + /// Enter watermeter end states here + /// + if (dataEntryCmpnt != null) + { + string fileName = string.Format("{0}-{1}-end.bmp", test.Name, repetitionNr); //string.Format("{0}-end.bmp", test.Name); + + IValve triggerValve = null; + bool triggerSend = false; + if (dataEntryCmpnt is GenericDevices.IDataEntryForCamera) + { + string[] endImages = new string[sensPath.RegisterReaders.Length]; + + State state2 = State.Create(string.Format("{0}({1}) : Grabbing images", test.Method, test.Name)) + .AddOperation(checkUiOp); + for (int i = 0; i < sensPath.RegisterReaders.Length; i++) + { + GenericDevices.IRegReaderStillCamera roi = sensPath.RegisterReaders[i] as GenericDevices.IRegReaderStillCamera; + if (roi != null) + { + ///if exist valve trigger camera open + triggerValve = roi.GetValve(); + if (triggerValve != null && !triggerSend) + { + OpenValveGrabImage(cBrd,testInProgress,triggerValve, e, + string.Format("{0}({1}) : Grabbing images - valve open", test.Method, test.Name)); + triggerSend = true; + } + string directory = Path.Combine(Program.TempImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + Directory.CreateDirectory(directory); + endImages[i] = Path.Combine(directory, fileName); + state2.AddOperation(roi.GrabImageOp(endImages[i])); + state2.AddOperation(testInProgress); + } + else + { + /// Camera simulation + string directory = Path.Combine(Program.TempImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + Directory.CreateDirectory(directory); + endImages[i] = Path.Combine(directory, fileName); + } + } + state2.EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test)); + + if (e.Contains(Event.Error)) { retVal = Event.Error; break; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; break; } + } + while (e.Contains(Event.CameraBusy)); + + (dataEntryCmpnt as GenericDevices.IDataEntryForCamera).EndImages = endImages; + } + + ///valve trigger camera close + if (triggerValve != null) + { + CloseValveGrabImage(cBrd,testInProgress, triggerValve, e, + string.Format("{0}({1}) : Grabbing images - valve close", test.Method, test.Name)); + } + /////// + + Bridge.OnActivity(this, Strings.Enter_water_meter_data); + State state = State.Create(string.Format("{0}({1}) : Entering the end-state", test.Method, test.Name)); + if (heatMetersTestParams != null && dataEntryCmpnt is GenericDevices.IHasHeatMtrStatesForm) + { + state.AddOperation((dataEntryCmpnt as GenericDevices.IHasHeatMtrStatesForm). + ShowTestEndFormOp(sensPath.RegisterReaders, + volumeCTV, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty, + refEnergy, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty)); + } + else + { + state.AddOperation(dataEntryCmpnt.ShowTestEndFormOp(sensPath.RegisterReaders, + volumeCTV, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty)); + } + state.AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress) + .EnterState(); + do { + e = StateMachine.WaitRunDevsRunOps(); + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + } + while (!e.Contains(Event.ModelessFormClosed)); + + + if (heatMetersTestParams != null) + { + for (int i = 0; i < TBF.Data.HeatMetersCount; i++) + { + Rig.RegisterReaders.StandingStartStop.RegisterReader volumeRegisterReader = + sensPath.RegisterReaders[2 * i] as Rig.RegisterReaders.StandingStartStop.RegisterReader; + + Rig.RegisterReaders.StandingStartStop.RegisterReader energyRegisterReader = + sensPath.RegisterReaders[2 * i + 1] as Rig.RegisterReaders.StandingStartStop.RegisterReader; + + if (volumeRegisterReader != null) volumeRegisterReader.EndWMState = dataEntryCmpnt.WMEndState(i); + if (energyRegisterReader != null && dataEntryCmpnt is GenericDevices.IHasHeatMtrStatesForm) + { + energyRegisterReader.EndWMState = (float)(dataEntryCmpnt as GenericDevices.IHasHeatMtrStatesForm).EnergyEndState(i); + } + } + } + else + { + for (int i = 0; i < waterMetersCount; i++) + { + GenericDevices.IRegReader rr = sensPath.RegisterReaders[i]; + + if (rr is Rig.RegisterReaders.StandingStartStop.RegisterReader) + (rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).EndWMState = dataEntryCmpnt.WMEndState(i); + + if (rr is Rig.Network.Camera.RoiForFixedStart.Roi) + (rr as Rig.Network.Camera.RoiForFixedStart.Roi).EndWMState = dataEntryCmpnt.WMEndState(i); + + if (rr is Rig.Network.Camera.RoiForFixedStartKeyence.Roi) + { + (rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).EndWMState = + dataEntryCmpnt.WMEndState(i); + log.DebugFormat(" StandingStartMassCollectionSeq.cs - EndWMState [{0}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMEndState(i)); + } + if(rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi) + (rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).EndWMState = dataEntryCmpnt.WMEndState(i); + + } + } + + if (dataEntryCmpnt is IDataEntryForCamera && (dataEntryCmpnt as IDataEntryForCamera).SaveImages) + { + log.Debug("Save images EndWMState..."); + /// SaveImages==true ... copy images to the directory that will be archived at the end of the cycle + for (int i = 0; i < sensPath.RegisterReaders.Length; i++) + { + var roi = sensPath.RegisterReaders[i] as IRegReaderStillCamera; + if (roi != null) + { + string srcDir = Path.Combine(Program.TempImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + string destDir = Path.Combine(Program.ImagesDir, BatchRslts.Batch.BatchNr.ToString(), (i + 1).ToString()); + try + { + if (File.Exists(Path.Combine(srcDir, fileName))) + { + Directory.CreateDirectory(destDir); + string destFName = string.IsNullOrEmpty((dataEntryCmpnt as IDataEntryForCamera).TestEndImgName(i, testName)) + ? fileName : (dataEntryCmpnt as IDataEntryForCamera).TestEndImgName(i, testName); + File.Copy(Path.Combine(srcDir, fileName), Path.Combine(destDir, destFName), true); + log.DebugFormat("Save images sourceFile: {0}, destFile: {1} ",Path.Combine(srcDir, fileName), Path.Combine(destDir, destFName)); + } + } + catch (Exception exc) + { + log.ErrorFormat("Failed to copy image {0} to {1}: {2}", fileName, destDir, exc.Message); + } + } + } + } + } + + //------------------------------------------------ + Bridge.OnActivity(this, Strings.Test_completed); + //------------------------------------------------ + + /// Make sure the CycleBeginForm is closed so that water meter data (s/n) can be copied into results + if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stopTest; + + /// + /// Populate TestResult data entity with data + /// + Results.Entities.TestRslt tstRslt = BatchRslts.GetTestRslt(testName, test.Part); + + bool stopCycle = false; + if (tstRslt != null) + { + Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters); + + /// Raw data + UpdateTempPressDensAmb(tstRslt); + tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName; + tstRslt.StartTime = TestStartTime; + tstRslt.EndTime = TestEndTime; + tstRslt.FlowSetTime = flowSetTime; + tstRslt.TestTime = Math.Max(1.0, DateTimeBox.DurationSec(timeStampStart, timeStampEnd)); /// Min. 1s to prevent division by zero + tstRslt.PulsesMaster = Convert.ToDouble(cBrd.RefPulses); /// Pulses of the master flow meter (test total) + tstRslt.MassStartRaw = StartMass.Val; + tstRslt.MassEndRaw = EndMass.Val; + tstRslt.TimeBtwnMassMsrmnts = tMass2 - tMass1; + + /// Corrected values + tstRslt.MassStart = massStart; + tstRslt.MassEnd = massEnd; + tstRslt.MassOfEvapWater = massOfEvaporatedWater; + + /// Main results + tstRslt.VolumeCTV = volumeCTV; /// [l] 1000.0f is because density is in [kg/m3] + tstRslt.Flow = 3.6 * volumeCTV / tstRslt.TestTime; /// [m3/h] + + if (cBrd is ControlBoard.Uni.UniCB) + { + /// Test bench with Uni control board and q reference flow meter + tstRslt.ConstMasterRaw = outPath.FlowMeter.LtrPerPulse; + tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean); + tstRslt.VolumeMaster = tstRslt.ConstMasterRaw * tstRslt.PulsesMaster; /// [l] volume from the master flow meter + tstRslt.ConstMaster = (tstRslt.VolumeMaster != 0) ? (tstRslt.ConstMasterRaw * tstRslt.VolumeCTV / tstRslt.VolumeMaster) : tstRslt.ConstMasterCorr; + } + else + { + /// Test bench with Papouch control board without reference flow meter + tstRslt.VolumeMaster = volumeCTV; /// [l] volume from the master flow meter + tstRslt.ConstMasterRaw = 1; /// Uncorrected master flowmeter coefficient + tstRslt.ConstMasterCorr = 1; /// Corrected master pulses per liter + tstRslt.ConstMaster = 1; + } + tstRslt.ErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV); + + tstRslt.FlowMean = (float)RefFlowStat.Average; + tstRslt.FlowStart = (float)RefFlowStat.First; + tstRslt.FlowEnd = (float)RefFlowStat.Last; + tstRslt.FlowMin = (float)RefFlowStat.Min; + tstRslt.FlowMax = (float)RefFlowStat.Max; + + tstRslt.DiverterStart = startSwitchTime.Val; + tstRslt.DiverterEnd = stopSwitchTime.Val; + + long infoFlags = 0; + tstRslt.ErrorFlags = (ErrorFlagsComp != null) ? ErrorFlagsComp.GetErrorFlags(tstRslt, false, true, startSwitchTime.Val, stopSwitchTime.Val, out infoFlags, out stopCycle) : 0; + tstRslt.InfoFlags = infoFlags; + + if (compound) + { + /// + /// Compound meters + /// + for (int i = 0; i < BatchRslts.WMPositionsCount; i++) + { + if (!test.IsPartCompatible(Utils.PartNr(i + 1, BatchRslts.Batch.Compound))) continue; + + Results.Entities.MeterTestRslt mainMeterRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.CompoundMain); + Results.Entities.MeterTestRslt auxMeterRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.CompoundAux); + + for (int isAux = 0; isAux <= 1; isAux++) /// 0=main, 1=aux + { + Results.Entities.MeterTestRslt meterRslt = (isAux == 0) ? mainMeterRslt : auxMeterRslt; + GenericDevices.IRegReader regReader = sensPath.RegisterReaders[2 * i + isAux]; + + if (meterRslt != null && regReader != null) + { + meterRslt.RegReaderType = (int)regReader.RegisterReaderType; + meterRslt.PulsesPerLiter = regReader.PulsesPerLtr; + meterRslt.VolumeStart = regReader.BeginWMState; /// [l] + meterRslt.VolumeEnd = regReader.EndWMState; /// [l] + meterRslt.VolumeMeter = Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart); /// [l] + meterRslt.VolumeRef = tstRslt.VolumeCTV; /// [l] + meterRslt.PulsesMeter = meterRslt.VolumeMeter; + meterRslt.PulsesMaster = tstRslt.PulsesMaster; + meterRslt.TestTime = tstRslt.TestTime; + meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef); /// Not used for evaluation + } + } + + Results.Entities.MeterTestRslt compoundMeterRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.Compound); + + if (compoundMeterRslt != null && mainMeterRslt != null && auxMeterRslt != null) + { + compoundMeterRslt.VolumeRef = tstRslt.VolumeCTV; /// [l] must be calculated before main & aux. meter error + compoundMeterRslt.VolumeMeter = mainMeterRslt.VolumeMeter + auxMeterRslt.VolumeMeter; + compoundMeterRslt.PulsesMaster = tstRslt.PulsesMaster; + compoundMeterRslt.TestTime = tstRslt.TestTime; + compoundMeterRslt.Error = Formulas.ErrorFromVolumes(compoundMeterRslt.VolumeMeter, compoundMeterRslt.VolumeRef); + compoundMeterRslt.Passed = (compoundMeterRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty) + && (compoundMeterRslt.Error <= test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime) - test.Uncertainty) + && (tstRslt.ErrorFlags == 0); + mainMeterRslt.Passed = auxMeterRslt.Passed = compoundMeterRslt.Passed; + mainMeterRslt.TestDone = auxMeterRslt.TestDone = compoundMeterRslt.TestDone = true; + tstRslt.TestDone = true; + } + } + } + else if (heatMetersTestParams != null) + { + /// + /// Heat meters + /// + tstRslt.RefEnergy = Energy.Sum * tstRslt.VolumeCTV / VolumeForEnergy.Sum; /// [J] = [J] * [l] / [l] + + tstRslt.Custom1 = (float)TempRefHiStat.Average; + tstRslt.Custom2 = (float)TempRefHiStat.First; + tstRslt.Custom3 = (float)TempRefHiStat.Last; + tstRslt.Custom4 = (float)TempRefHiStat.Min; + tstRslt.Custom5 = (float)TempRefHiStat.Max; + tstRslt.Custom6 = (float)TempRefLoStat.Average; + tstRslt.Custom7 = (float)TempRefLoStat.First; + tstRslt.Custom8 = (float)TempRefLoStat.Last; + tstRslt.Custom9 = (float)TempRefLoStat.Min; + tstRslt.Custom10 = (float)TempRefLoStat.Max; + + for (int i = 0; i < BatchRslts.WMPositionsCount; i++) + { + if (!test.IsPartCompatible(Utils.PartNr(i + 1, BatchRslts.Batch.Compound))) continue; + + Results.Entities.MeterTestRslt volumeRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.HeatMeterVolume); + Results.Entities.MeterTestRslt energyRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.HeatMeterEnergy); + + GenericDevices.IRegReader volumeRegReader = + (sensPath.RegisterReaders.Length > 2 * i) ? sensPath.RegisterReaders[2 * i] : null; + + GenericDevices.IRegReader energyRegReader = + (sensPath.RegisterReaders.Length > 2 * i + 1) ? sensPath.RegisterReaders[2 * i + 1] : null; + + if (volumeRslt != null && volumeRegReader != null) + { + volumeRslt.PulsesPerLiter = volumeRegReader.PulsesPerLtr; + volumeRslt.VolumeStart = volumeRegReader.BeginWMState; + volumeRslt.VolumeEnd = volumeRegReader.EndWMState; + volumeRslt.VolumeMeter = volumeRslt.VolumeEnd - volumeRslt.VolumeStart; + volumeRslt.VolumeRef = tstRslt.VolumeCTV; + volumeRslt.PulsesMeter = volumeRslt.VolumeMeter; + volumeRslt.PulsesMaster = tstRslt.PulsesMaster; /// <----------------- ??? + volumeRslt.TestTime = tstRslt.TestTime; + + volumeRslt.Error = Formulas.ErrorFromVolumes(volumeRslt.VolumeMeter, volumeRslt.VolumeRef); + volumeRslt.Passed = !heatMetersTestParams.EvaluateVolume || + ((volumeRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty) && + (volumeRslt.Error <= test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime) - test.Uncertainty) && + (tstRslt.ErrorFlags == 0)); + volumeRslt.TestDone = true; + tstRslt.TestDone = true; + } + + if (energyRslt != null && energyRegReader != null && dataEntryCmpnt is GenericDevices.IHasHeatMtrStatesForm) + { + volumeRslt.PulsesPerLiter = energyRegReader.PulsesPerLtr; + energyRslt.VolumeStart = (dataEntryCmpnt as GenericDevices.IHasHeatMtrStatesForm).EnergyStartState(i); + energyRslt.VolumeEnd = (dataEntryCmpnt as GenericDevices.IHasHeatMtrStatesForm).EnergyEndState(i); + energyRslt.VolumeMeter = energyRslt.VolumeEnd - energyRslt.VolumeStart; + energyRslt.VolumeRef = tstRslt.RefEnergy; + energyRslt.PulsesMeter = energyRslt.VolumeMeter; + energyRslt.PulsesMaster = tstRslt.PulsesMaster; /// <----------------- ??? + + energyRslt.Error = Formulas.ErrorFromVolumes(energyRslt.VolumeMeter, energyRslt.VolumeRef); + energyRslt.Passed = (energyRslt.Error >= heatMetersTestParams.ErrorLimitLo) + && (energyRslt.Error <= heatMetersTestParams.ErrorLimitHi) + && (tstRslt.ErrorFlags == 0); + energyRslt.TestDone = true; + tstRslt.TestDone = true; + } + } + } + else + { + /// + /// Single meters + /// + for (int i = 0; i < BatchRslts.WMPositionsCount; i++) + { + if (!test.IsPartCompatible(Utils.PartNr(i + 1, BatchRslts.Batch.Compound))) continue; + + Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.Single); + GenericDevices.IRegReader regReader = sensPath.RegisterReaders[i]; + + if (meterRslt != null && regReader != null) + { + meterRslt.RegReaderType = (int)regReader.RegisterReaderType; + meterRslt.PulsesPerLiter = regReader.PulsesPerLtr; + meterRslt.VolumeStart = regReader.BeginWMState; + meterRslt.VolumeEnd = regReader.EndWMState; + meterRslt.VolumeMeter = Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart); + meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter + meterRslt.PulsesMeter = meterRslt.VolumeMeter; + meterRslt.PulsesMaster = tstRslt.PulsesMaster; + meterRslt.TestTime = tstRslt.TestTime; + meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef); + meterRslt.Passed = (meterRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty) + && (meterRslt.Error <= test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime) - test.Uncertainty) + && (tstRslt.ErrorFlags == 0); + meterRslt.TestDone = true; + tstRslt.TestDone = true; + } + } + } + + tstRslt.Components = Results.Entities.Components + .UpdateList(BatchRslts.ComponentsList, + new Results.Entities.Components((BenchInfo != null) ? BenchInfo.TestBenchId : 1, + (BenchInfo != null) ? BenchInfo.TestBenchName : "testbench", + inPath.Pump != null ? inPath.Pump.Name : string.Empty, + outPath.FlowMeter != null ? outPath.FlowMeter.Name : string.Empty, + scale != null ? scale.Name : string.Empty, + outPath.RegValve != null ? outPath.RegValve.Name : string.Empty, + outPath.Diverter != null ? outPath.Diverter.Name : string.Empty)); + + /// Update water meter error flags + if (ErrorFlagsComp != null) + { + if (BatchRslts.Batch != null && BatchRslts.Batch.WaterMeters != null) + { + for (int i = 0; i < BatchRslts.WMPositionsCount; i++) + { + if (BatchRslts.Batch.WaterMeters[i] != null && !BatchRslts.Batch.WaterMeters[i].Disabled) + { + long wmInfoFlags; + BatchRslts.Batch.WaterMeters[i].ErrorFlags = ErrorFlagsComp.GetWMtrErrorFlags(BatchRslts.Batch.WaterMeters[i].MeterTestRslts, out wmInfoFlags); + BatchRslts.Batch.WaterMeters[i].InfoFlags = wmInfoFlags; + } + } + } + } + + /// Update results + Bridge.OnTestCompleted(this, new TestCompletedEventArgs(testName, tstRslt)); + } + + Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.TransitionAfter)); + + /// Append the results to the CSV-file + allResults.Info(TestResult2CsvLine(testName, test.Part)); + + if (stopCycle) retVal = Event.ErrorFlagsStop; + + stopTest: + + StopRecordingStatistics(); + + /// + /// Quit this sequence + /// + if (isLastRepetition || retVal == Event.UiCmdStop + || retVal == Event.OpArgumentError + || retVal == Event.RecoverableError + || retVal == Event.ErrorFlagsStop + || retVal == Event.Error + || retVal == Event.ConfigurationError) + { + cBrd.StopAll(false); + } + + return new List { retVal }; + } + } +} diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj index dbe1e3e97..839ba193e 100644 --- a/TBF/TBF.csproj +++ b/TBF/TBF.csproj @@ -1643,6 +1643,21 @@ + + + + + + + UserControl + + + TestMethodCfgCtrl.cs + + + + + @@ -3440,6 +3455,9 @@ TestMethodCfgCtrl.cs + + TestMethodCfgCtrl.cs + TestMethodCfgCtrl.cs