/// /// Copyright (c) 2013-2017 Sensus Metering Systems /// using System; using System.Collections.Generic; using System.Globalization; using System.IO; namespace Config.Entities { /// /// Test, consisting of one or more repetitions of the test 'SingleTest'. /// public class Test : IHasName, IHasItemNr { public virtual int Id { get; protected set; } public virtual int ItemNr { get; set; } public virtual string Name { get; set; } public virtual int Part { get; set; } /// Part=0 ... test of all WM-s /// Part>0 ... part of a set of tests with the same Name: subset of WM-s is given by MetersPath public virtual sbyte Publish { get; set; } /// 0=no, 1=in all protocols, 2=on screen, 3=internal public virtual bool DoEvaluate { get; set; } public virtual float Qfrom { get; set; } /// Water flow low limit in [m3/h] public virtual float Qto { get; set; } /// Water flow high limit in [m3/h] public virtual float Volume { get; set; } /// Test volume (target) in [l] public virtual float TstTime { get; set; } /// Test time (estimate) in [s] public virtual string Method { get; set; } public virtual float ErrLimLo { get; set; } /// in [%] (usually < 0) public virtual float ErrLimHi { get; set; } /// in [%] (usually > 0) public virtual float Uncertainty { get; set; } /// int [%] makes error limits tighter: 0 <= Uncertainty <= abs(ErrLimXx) public virtual int Repeats { get; set; } public virtual bool DoDraining { get; set; } public virtual bool DoZeroing { get; set; } public virtual bool DoControlWaterTemp { get; set; } public virtual float TempLimLo { get; set; } /// Lower limit for the controlled temperature public virtual float TempLimHi { get; set; } /// Upper limit for the controlled temperature public virtual float PumpPower { get; set; } /// Power of the pump in [%] in the range 0 .. 100.0f, use values 0% and 100% for non-FM pumps public virtual int MassRepeats { get; set; } /// Number of mass. measurements at the beginning/end of test, 0 = default (=5) public virtual float MassSpread { get; set; } /// Max spread of mass. measurements at the beginning/end of test, 0 = default public virtual MassMethod MassMethod { get; set; } /// method of mass. measurement at the beginning/end of test: false=slow (precise), true=using immediate mass measurement and evaluation public virtual int TimeBeforeFlow { get; set; } /// Delay time before the start of flow control in [s] public virtual int TimeFlow2Mass { get; set; } /// Delay time from the flow stable to the 1st mass measurement in [s] public virtual int TimePump2StartV { get; set; } /// Delay time from the start of the pump to opening the start valve in [s] public virtual int TimeStop2Mass { get; set; } /// Delay time from the test end (diverted) to the 2nd mass measuremen in [s] public virtual double TolerRed { get; set; } /// = Filter public virtual TestRedType RedType { get; set; } public virtual string FeedingPath { get; set; } public virtual string BenchPath { get; set; } public virtual string OutputPath { get; set; } public virtual string MetersPath { get; set; } #if HEAT_METERS public virtual string HeatMetersPath { get; set; } #endif public virtual string RelTransBefore { get; set; } public virtual string RelTransBetween { get; set; } public virtual string RelTransAfter { get; set; } public virtual string TransitionAfter { get; set; } public virtual IList MoreParams { get; set; } public virtual Procedure Procedure { get; set; } /// ------------- Additional stuff not mapped into the database ------------- public Test() { MoreParams = new List(); /// /// Default values /// Publish = (sbyte)Config.Entities.Publish.Always; DoEvaluate = true; Repeats = 1; DoDraining = false; DoZeroing = false; DoControlWaterTemp = false; TempLimLo = 15.0f; TempLimHi = 25.0f; ErrLimLo = -2.0f; /// [%] lower error limit ErrLimHi = 2.0f; /// [%] upper error limit Uncertainty = 0; PumpPower = 60.0f; /// [%] MassRepeats = 0; /// default MassSpread = 0; /// default MassMethod = MassMethod.Scale; /// default TimeBeforeFlow = 10; /// [s] time before the start of flow control in [s] TimeFlow2Mass = 5; /// [s] time from the flow stable to the 1st mass measurement in [s] TimePump2StartV = 1; /// [s] time from the 1st mass measurement to the test start in [s] TimeStop2Mass = 5; /// [s] between the test end and the final mass measurement TolerRed = 0; /// = Filter parameter RelTransBefore = string.Empty; RelTransBetween = string.Empty; RelTransAfter = string.Empty; TransitionAfter = string.Empty; } public Test(string name, int itemNr, Procedure procedure) : this() { Name = name; ItemNr = itemNr; Procedure = procedure; } // Makes a new copy of this object (not just a reference) public virtual Test Clone() { Test result = new Test(Name, ItemNr, Procedure); result.Part = Part; result.Publish = Publish; result.DoEvaluate = DoEvaluate; result.Qfrom = Qfrom; result.Qto = Qto; result.Volume = Volume; result.TstTime = TstTime; result.Repeats = Repeats; result.DoDraining = DoDraining; result.DoZeroing = DoZeroing; result.DoControlWaterTemp = DoControlWaterTemp; result.TempLimLo = TempLimLo; result.TempLimHi = TempLimHi; result.PumpPower = PumpPower; result.MassRepeats = MassRepeats; result.MassSpread = MassSpread; result.MassMethod = MassMethod; result.TimeBeforeFlow = TimeBeforeFlow; result.TimeFlow2Mass = TimeFlow2Mass; result.TimePump2StartV = TimePump2StartV; result.TimeStop2Mass = TimeStop2Mass; result.Method = Method; result.ErrLimLo = ErrLimLo; result.ErrLimHi = ErrLimHi; result.Uncertainty = Uncertainty; result.TolerRed = TolerRed; result.RedType = RedType; result.FeedingPath = FeedingPath; result.BenchPath = BenchPath; result.OutputPath = OutputPath; result.MetersPath = MetersPath; #if HEAT_METERS result.HeatMetersPath = HeatMetersPath; #endif result.RelTransBefore = RelTransBefore; result.RelTransBetween = RelTransBetween; result.RelTransAfter = RelTransAfter; result.TransitionAfter = TransitionAfter; foreach (var prms in MoreParams) { result.MoreParams.Add(prms.Clone()); } return result; } public virtual void Export(StreamWriter output) { CultureInfo ci = CultureInfo.InvariantCulture; output.WriteLine(Name); output.WriteLine(Part.ToString(ci)); output.WriteLine(Publish.ToString(ci)); output.WriteLine(DoEvaluate.ToString()); output.WriteLine(Qfrom.ToString(ci)); output.WriteLine(Qto.ToString(ci)); output.WriteLine(Volume.ToString(ci)); output.WriteLine(TstTime.ToString(ci)); output.WriteLine(Method); output.WriteLine(ErrLimLo.ToString(ci)); output.WriteLine(ErrLimHi.ToString(ci)); output.WriteLine(Uncertainty.ToString(ci)); output.WriteLine(Repeats.ToString(ci)); output.WriteLine(DoDraining.ToString()); output.WriteLine(DoZeroing.ToString()); output.WriteLine(DoControlWaterTemp.ToString()); output.WriteLine(TempLimLo.ToString(ci)); output.WriteLine(TempLimHi.ToString(ci)); output.WriteLine(PumpPower.ToString(ci)); output.WriteLine(MassRepeats.ToString(ci)); output.WriteLine(MassSpread.ToString(ci)); output.WriteLine(((byte)MassMethod).ToString(ci)); output.WriteLine(TimeBeforeFlow.ToString(ci)); output.WriteLine(TimeFlow2Mass.ToString(ci)); output.WriteLine(TimePump2StartV.ToString(ci)); output.WriteLine(TimeStop2Mass.ToString(ci)); output.WriteLine(FeedingPath); output.WriteLine(BenchPath); output.WriteLine(OutputPath); output.WriteLine(MetersPath); output.WriteLine(RelTransBefore); output.WriteLine(RelTransBetween); output.WriteLine(RelTransAfter); output.WriteLine(TransitionAfter); foreach (var prms in MoreParams) { prms.Export(output); } output.WriteLine(); } public static Test Import(StreamReader input, Procedure newProcedure) { string firstLine = input.ReadLine(); if (string.IsNullOrEmpty(firstLine)) { return null; } CultureInfo ci = CultureInfo.InvariantCulture; Test tst = new Test(); tst.Name = firstLine; tst.Part = int.Parse(input.ReadLine(), ci); tst.Publish = sbyte.Parse(input.ReadLine(), ci); tst.DoEvaluate = bool.Parse(input.ReadLine()); tst.Qfrom = float.Parse(input.ReadLine(), ci); tst.Qto = float.Parse(input.ReadLine(), ci); tst.Volume = float.Parse(input.ReadLine(), ci); tst.TstTime = float.Parse(input.ReadLine(), ci); tst.Method = input.ReadLine(); tst.ErrLimLo = float.Parse(input.ReadLine(), ci); tst.ErrLimHi = float.Parse(input.ReadLine(), ci); tst.Uncertainty = float.Parse(input.ReadLine(), ci); tst.Repeats = int.Parse(input.ReadLine(), ci); tst.DoDraining = bool.Parse(input.ReadLine()); tst.DoZeroing = bool.Parse(input.ReadLine()); tst.DoControlWaterTemp = bool.Parse(input.ReadLine()); tst.TempLimLo = float.Parse(input.ReadLine(), ci); tst.TempLimHi = float.Parse(input.ReadLine(), ci); tst.PumpPower = float.Parse(input.ReadLine(), ci); tst.MassRepeats = int.Parse(input.ReadLine(), ci); tst.MassSpread = float.Parse(input.ReadLine(), ci); tst.MassMethod = (MassMethod)byte.Parse(input.ReadLine(), ci); tst.TimeBeforeFlow = int.Parse(input.ReadLine(), ci); tst.TimeFlow2Mass = int.Parse(input.ReadLine(), ci); tst.TimePump2StartV = int.Parse(input.ReadLine(), ci); tst.TimeStop2Mass = int.Parse(input.ReadLine(), ci); tst.FeedingPath = input.ReadLine(); tst.BenchPath = input.ReadLine(); tst.OutputPath = input.ReadLine(); tst.MetersPath = input.ReadLine(); tst.RelTransBefore = input.ReadLine(); tst.RelTransBetween = input.ReadLine(); tst.RelTransAfter = input.ReadLine(); tst.TransitionAfter = input.ReadLine(); while (true) { ComponentTest prms = ComponentTest.Import(input, tst); if (prms == null) break; else tst.MoreParams.Add(prms); } tst.Procedure = newProcedure; return tst; } public virtual string Compare(StreamReader inp) { System.Text.StringBuilder diff = new System.Text.StringBuilder(); string fmt = string.Format("Test {0} : ", Name) + "{0} = {1}\r\n (in the file {2})\r\n"; string ln; CultureInfo ci = CultureInfo.InvariantCulture; string firstLine = inp.ReadLine(); if (string.IsNullOrEmpty(firstLine)) return string.Format("Test {0} is missing in the file\r\n", Name); if (Name != firstLine) { diff.AppendFormat(fmt, "Name", Name, firstLine); }; ln = inp.ReadLine(); if (ln != Part.ToString(ci)) { diff.AppendFormat(fmt, "Part", Part.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Publish.ToString(ci)) { diff.AppendFormat(fmt, "Publish", Publish.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != DoEvaluate.ToString(ci)) { diff.AppendFormat(fmt, "Evaluate", DoEvaluate.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Qfrom.ToString(ci)) { diff.AppendFormat(fmt, "Qfrom", Qfrom.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Qto.ToString(ci)) { diff.AppendFormat(fmt, "Qto", Qto.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Volume.ToString(ci)) { diff.AppendFormat(fmt, "Volume", Volume.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TstTime.ToString(ci)) { diff.AppendFormat(fmt, "TstTime", TstTime.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Method) { diff.AppendFormat(fmt, "Method", Method, ln); }; ln = inp.ReadLine(); if (ln != ErrLimLo.ToString(ci)) { diff.AppendFormat(fmt, "ErrLimLo", ErrLimLo.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != ErrLimHi.ToString(ci)) { diff.AppendFormat(fmt, "ErrLimHi", ErrLimHi.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Uncertainty.ToString(ci)) { diff.AppendFormat(fmt, "Uncertainty", Uncertainty.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != Repeats.ToString(ci)) { diff.AppendFormat(fmt, "Repeats", Repeats.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != DoDraining.ToString(ci)) { diff.AppendFormat(fmt, "Draining", DoDraining.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != DoZeroing.ToString(ci)) { diff.AppendFormat(fmt, "Zeroing", DoZeroing.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != DoControlWaterTemp.ToString()) { diff.AppendFormat(fmt, "DoControlWaterTemp", DoControlWaterTemp.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TempLimLo.ToString(ci)) { diff.AppendFormat(fmt, "TempLimLo", TempLimLo.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TempLimHi.ToString(ci)) { diff.AppendFormat(fmt, "TempLimHi", TempLimHi.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != PumpPower.ToString(ci)) { diff.AppendFormat(fmt, "PumpPower", PumpPower.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != MassRepeats.ToString(ci)) { diff.AppendFormat(fmt, "MassRepeats", MassRepeats.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != MassSpread.ToString(ci)) { diff.AppendFormat(fmt, "MassSpread", MassSpread.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != ((byte)MassMethod).ToString(ci)) { diff.AppendFormat(fmt, "MassMethod", ((byte)MassMethod).ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TimeBeforeFlow.ToString(ci)) { diff.AppendFormat(fmt, "TimeBeforeFlow", TimeBeforeFlow.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TimeFlow2Mass.ToString(ci)) { diff.AppendFormat(fmt, "TimeFlow2Mass", TimeFlow2Mass.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TimePump2StartV.ToString(ci)) { diff.AppendFormat(fmt, "TimePump2StartV", TimePump2StartV.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != TimeStop2Mass.ToString(ci)) { diff.AppendFormat(fmt, "TimeStop2Mass", TimeStop2Mass.ToString(ci), ln); }; ln = inp.ReadLine(); if (ln != FeedingPath) { diff.AppendFormat(fmt, "FeedingPath", FeedingPath, ln); }; ln = inp.ReadLine(); if (ln != BenchPath) { diff.AppendFormat(fmt, "BenchPath", BenchPath, ln); }; ln = inp.ReadLine(); if (ln != OutputPath) { diff.AppendFormat(fmt, "OutputPath", OutputPath, ln); }; ln = inp.ReadLine(); if (ln != MetersPath) { diff.AppendFormat(fmt, "MetersPath", MetersPath, ln); }; ln = inp.ReadLine(); if (ln != RelTransBefore) { diff.AppendFormat(fmt, "RelTransBefore", RelTransBefore, ln); }; ln = inp.ReadLine(); if (ln != RelTransBetween) { diff.AppendFormat(fmt, "RelTransBetween", RelTransBetween, ln); }; ln = inp.ReadLine(); if (ln != RelTransAfter) { diff.AppendFormat(fmt, "RelTransAfter", RelTransAfter, ln); }; ln = inp.ReadLine(); if (ln != TransitionAfter) { diff.AppendFormat(fmt, "TransitionAfter", TransitionAfter, ln); }; return diff.ToString(); } public override string ToString() { string partStr = (Part > 0) ? string.Format(", part {0}", Part) : string.Empty; return string.Format("{0}(P.{1},{2}){3}", Name, ((Publish)Publish).ToString(), DoEvaluate ? "E" : "-", partStr); } } }