MassMethod : bool -> enum

This commit is contained in:
Milan Hanajik 2017-03-28 21:40:27 +02:00
parent 214a570ca6
commit 2ca5eec8e1
10 changed files with 126 additions and 78 deletions

View File

@ -190,6 +190,26 @@ namespace Config.Entities
Count
}
public enum MassMethod : byte
{
#if LANG_DE
/// nemecky
[Description("Waage")] Scale,
[Description("Spanne")] Spread,
[Description("Standardabw.")] StdDev,
#elif LANG_CS
/// cesky
[Description("váhou")] Scale,
[Description("max.rozdíl")] Spread,
[Description("std.dev.")] StdDev,
#else
[Description("Scale")] Scale,
[Description("Spread")] Spread,
[Description("Std.dev.")] StdDev,
#endif
Count
}
public enum TestRedType
{
Fix,

View File

@ -30,15 +30,15 @@ namespace Config.Entities
public virtual int Repeats { get; set; }
public virtual bool Emptying { get; set; }
public virtual bool Zeroing { get; set; }
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 bool 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 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; }
@ -70,21 +70,21 @@ namespace Config.Entities
Repeats = 1;
Emptying = false;
Zeroing = false;
ErrLimLo = -2.0f; /// [%] lower error limit
ErrLimHi = 2.0f; /// [%] upper error limit
ErrLimLo = -2.0f; /// [%] lower error limit
ErrLimHi = 2.0f; /// [%] upper error limit
Uncertainty = 0;
PumpPower = 60.0f; /// [%]
MassRepeats = 0; /// default
MassSpread = 0; /// default
MassMethod = false; /// 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;
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;
RelTransAfter = string.Empty;
TransitionAfter = string.Empty;
}

View File

@ -27,7 +27,8 @@ namespace Config.Mappings
Map(x => x.PumpPower);
Map(x => x.MassRepeats);
Map(x => x.MassSpread);
Map(x => x.MassMethod);
Map(x => x.MassMethod)
.CustomType<byte>();
Map(x => x.TimeBeforeFlow);
Map(x => x.TimeFlow2Mass);
Map(x => x.TimePump2StartV)

View File

@ -49,7 +49,7 @@ namespace TBF.BenchControl.Dummy.Balance
return this;
}
public IOperation ReadStableMassOp(ref TBF.Boxes.DoubleBox mass, int readingsCount, double maxSpread, bool method)
public IOperation ReadStableMassOp(ref TBF.Boxes.DoubleBox mass, int readingsCount, double maxSpread, Config.Entities.MassMethod method)
{
mass.Val = 0;
return this;

View File

@ -78,6 +78,6 @@ namespace TBF.BenchControl.GenericDevices
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
/// <returns>ReadMassAverageOp instance reference casted to IOperaton</returns>
IOperation ReadStableMassOp(ref DoubleBox mass, int readingsCount, double maxSpread, bool method);
IOperation ReadStableMassOp(ref DoubleBox mass, int readingsCount, double maxSpread, Config.Entities.MassMethod method);
}
}

View File

@ -311,7 +311,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
/// <returns>ReadMassAverageOp instance reference casted to IOperaton</returns>
public IOperation ReadStableMassOp(ref DoubleBox mass, int readingsCount, double maxSpread, bool method)
public IOperation ReadStableMassOp(ref DoubleBox mass, int readingsCount, double maxSpread, Config.Entities.MassMethod method)
{
return new ReadStableMassOp(this, ref mass, readingsCount, maxSpread, method);
}

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2015-2016 Sensus Metering Systems
/// Copyright (c) 2015-2017 Sensus Metering Systems
///
using System;
using log4net;
@ -22,8 +22,8 @@ namespace TBF.BenchControl.MettlerToledo.Multi
/// Set by the constructor
BalanceDev balanceDev;
int totalReadingsCount;
double maxSpread; /// Maximum spread of measurements in kg (otherwise the measurement continues)
bool method; /// false = slow (precise), true = fast (immediate)
double maxSpread; /// Maximum spread of measurements in kg (otherwise the measurement continues)
Config.Entities.MassMethod method; /// false = slow (precise), true = fast (immediate)
DoubleBox result;
bool started;
@ -36,24 +36,14 @@ namespace TBF.BenchControl.MettlerToledo.Multi
/// <param name="readingsCount">Required mass readings count (>= 3)</param>
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
public ReadStableMassOp(BalanceDev balanceDev, ref DoubleBox result, int readingsCount, double maxSpread, bool method)
public ReadStableMassOp(BalanceDev balanceDev, ref DoubleBox result, int readingsCount, double maxSpread, Config.Entities.MassMethod method)
{
if (balanceDev == null) throw new ArgumentNullException("balanceDev");
this.balanceDev = balanceDev;
if (readingsCount == 0)
this.totalReadingsCount = 5;
else if (readingsCount < 3)
this.totalReadingsCount = 3;
else
this.totalReadingsCount = readingsCount;
if (maxSpread == 0)
this.maxSpread = balanceDev.Capacity / 20000;
else
this.maxSpread = maxSpread;
this.method = method;
this.totalReadingsCount = (readingsCount < 4) ? 5 : readingsCount; /// readingsCount is at least 4
this.maxSpread = (maxSpread == 0) ? (balanceDev.Capacity / 20000.0) : maxSpread;
this.method = method;
this.result = result;

View File

@ -117,7 +117,7 @@ namespace TBF.BenchControl.MettlerToledo.Standard
log.FatalFormat("Successfully initialized device {0}", ToString());
}
public bool IsEmpty()
public override bool IsEmpty()
{
return (this.mass <= balanceCfg.Empty);
}
@ -490,7 +490,7 @@ namespace TBF.BenchControl.MettlerToledo.Standard
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
/// <returns>ReadMassAverageOp instance reference casted to IOperaton</returns>
public IOperation ReadStableMassOp(ref DoubleBox mass, int readingsCount, double maxSpread, bool method)
public IOperation ReadStableMassOp(ref DoubleBox mass, int readingsCount, double maxSpread, Config.Entities.MassMethod method)
{
return new ReadStableMassOp(this, ref mass, readingsCount, maxSpread, method);
}

View File

@ -18,8 +18,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard
/// Set by the constructor
BalanceDev balanceDev;
int totalReadingsCount;
double maxSpread; /// Maximum spread of measurements in kg (otherwise the measurement continues)
bool method; /// false = slow (precise), true = fast (immediate)
double maxSpread; /// Maximum spread of measurements in kg (otherwise the measurement continues)
Config.Entities.MassMethod method; /// by the scale, mass spread threshold or mass standard deviation threshold
DoubleBox result;
/// Operation specific
@ -33,10 +33,10 @@ namespace TBF.BenchControl.MettlerToledo.Standard
/// </summary>
/// <param name="balanceDev">Balance device instance</param>
/// <param name="result">Reference to the measured mass in kg</param>
/// <param name="readingsCount">Required mass readings count (>= 3)</param>
/// <param name="readingsCount">Required mass readings count (>= 4)</param>
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
public ReadStableMassOp(BalanceDev balanceDev, ref DoubleBox result, int readingsCount, double maxSpread, bool method)
public ReadStableMassOp(BalanceDev balanceDev, ref DoubleBox result, int readingsCount, double maxSpread, Config.Entities.MassMethod method)
{
if (balanceDev == null) throw new ArgumentNullException("balanceDev");
this.balanceDev = balanceDev;
@ -60,10 +60,10 @@ namespace TBF.BenchControl.MettlerToledo.Standard
currentReadingsCount = 0;
measurementCompleted = false;
if (method)
balanceDev.GetImmediateMassMeasurement();
else
if (method == Config.Entities.MassMethod.Scale)
balanceDev.GetStableMassMeasurement();
else
balanceDev.GetImmediateMassMeasurement();
}
/// <summary>Run this operation</summary>
@ -101,12 +101,13 @@ namespace TBF.BenchControl.MettlerToledo.Standard
if (currentReadingsCount >= totalReadingsCount)
{
Array.Sort(massReadings);
#if STABLE_MASS_EXTRAS
if (method)
if (method == Config.Entities.MassMethod.Spread)
{
/// Immediate mass measurement, end condition calculated below
Array.Sort(massReadings);
if ((massReadings[totalReadingsCount - 2] - massReadings[1]) <= maxSpread)
{
double massSum = 0;
@ -118,13 +119,31 @@ namespace TBF.BenchControl.MettlerToledo.Standard
return Event.BalanceDone; /// Mass has just been calculated
}
}
else if (method == Config.Entities.MassMethod.StdDev)
{
/// Immediate mass measurement, end condition calculated below
double massSum = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) massSum += massReadings[i];
double ave = (massSum / (totalReadingsCount - 2));
double sdev = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) sdev += ((massReadings[i] - ave) * (massReadings[i] - ave));
if (Math.Sqrt(sdev / (totalReadingsCount - 2)) <= maxSpread)
{
result.Val = ave;
log.InfoFormat("ReadStableMassOp.Run() ... valid mass={0} ... returning Event.BalanceDone", result.Val);
measurementCompleted = true;
return Event.BalanceDone; /// Mass has just been calculated
}
}
else
#endif
{
/// Stable mass measurement
/// Sort, exclude min. and max. values, calculate the average
Array.Sort(massReadings);
double massSum = 0;
for (int i = 1; i < totalReadingsCount - 1; i++) massSum += massReadings[i];
result.Val = (massSum / (totalReadingsCount - 2));
@ -145,10 +164,10 @@ namespace TBF.BenchControl.MettlerToledo.Standard
///
/// Start a new measurement
///
if (method)
balanceDev.GetImmediateMassMeasurement();
else
if (method == Config.Entities.MassMethod.Scale)
balanceDev.GetStableMassMeasurement();
else
balanceDev.GetImmediateMassMeasurement();
return Event.None;
}

View File

@ -783,9 +783,9 @@ namespace TBF
Qfrom,
Qto,
PumpPower,
#if STABLE_MASS_EXTRAS
MassRepeats,
MassSpread,
#if STABLE_MASS_EXTRAS
MassSpread,
MassMethod,
#endif
Time_Pump2StartV,
@ -804,9 +804,9 @@ namespace TBF
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Q_from_m3h, Width = 80 });
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Q_to_m3h, Width = 80 });
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Pump_power_pct, Width = 90 });
#if STABLE_MASS_EXTRAS
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Mass_repeats, Width = 90 });
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Mass_spread_kg, Width = 110 });
#if STABLE_MASS_EXTRAS
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Mass_spread_kg, Width = 110 });
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.Mass_method, Width = 90 });
#endif
parametersListViewEx.Columns.Add(new ColumnHeader { Text = Strings.TimePump2StartV_chdr, Width = 70 });
@ -821,8 +821,8 @@ namespace TBF
new TextBox(), /// Qfrom
new TextBox(), /// Qto
new ComboBox(), /// PumpPower
#if STABLE_MASS_EXTRAS
new TextBox(), /// MassRepeats
#if STABLE_MASS_EXTRAS
new TextBox(), /// MassSpread
new ComboBox(), /// MassMethod
#endif
@ -848,8 +848,10 @@ namespace TBF
((ComboBox)parametersEditors[(int)ParametersClmn.PumpPower]).Items.Add("98");
((ComboBox)parametersEditors[(int)ParametersClmn.PumpPower]).Items.Add("100");
#if STABLE_MASS_EXTRAS
((ComboBox)parametersEditors[(int)ParametersClmn.MassMethod]).Items.Add(Strings.stable);
((ComboBox)parametersEditors[(int)ParametersClmn.MassMethod]).Items.Add(Strings.fast);
for (MassMethod mm = 0; mm < MassMethod.Count; mm++)
{
((ComboBox)parametersEditors[(int)ParametersClmn.MassMethod]).Items.Add(mm.ToDescription());
}
#endif
foreach (var ctrl in parametersEditors)
{
@ -941,10 +943,10 @@ namespace TBF
/// Process subitems FeedingPath, ...
///
lviParameters.SubItems.Add(test.PumpPower.ToString("F1"));
#if STABLE_MASS_EXTRAS
lviParameters.SubItems.Add((test.MassRepeats < 4 ? 5 : test.MassRepeats).ToString());
lviParameters.SubItems.Add(test.MassSpread.ToString("F4"));
lviParameters.SubItems.Add(test.MassMethod ? Strings.fast : Strings.stable);
#if STABLE_MASS_EXTRAS
lviParameters.SubItems.Add(test.MassSpread.ToString("F4"));
lviParameters.SubItems.Add(test.MassMethod.ToDescription());
#endif
lviParameters.SubItems.Add(test.TimePump2StartV.ToString());
lviParameters.SubItems.Add(test.TimeBeforeFlow.ToString());
@ -1109,18 +1111,21 @@ namespace TBF
entity.PumpPower = powerPct;
}
int itmp;
#if STABLE_MASS_EXTRAS
if (int.TryParse(lvi.SubItems[(int)ParametersClmn.MassRepeats].Text, out itmp)) entity.MassRepeats = itmp;
entity.MassRepeats = int.Parse(lvi.SubItems[(int)ParametersClmn.MassRepeats].Text);
float massSpread;
#if STABLE_MASS_EXTRAS
float massSpread;
if (Utils.TryParseUFloat(lvi.SubItems[(int)ParametersClmn.MassSpread].Text, out massSpread) && massSpread >= 0)
{
entity.MassSpread = massSpread;
}
entity.MassMethod = lvi.SubItems[(int)ParametersClmn.MassMethod].Text.Equals(Strings.fast);
for (MassMethod mm = 0; mm < MassMethod.Count; mm++)
{
if (mm.ToDescription().Equals(lvi.SubItems[(int)ParametersClmn.MassMethod].Text)) entity.MassMethod = mm;
}
#endif
int itmp;
if (int.TryParse(lvi.SubItems[(int)ParametersClmn.Time_Pump2StartV].Text, out itmp)) entity.TimePump2StartV = itmp;
if (int.TryParse(lvi.SubItems[(int)ParametersClmn.Time_BeforeFlow].Text, out itmp)) entity.TimeBeforeFlow = itmp;
if (int.TryParse(lvi.SubItems[(int)ParametersClmn.Time_Flow2Mass].Text, out itmp)) entity.TimeFlow2Mass = itmp;
@ -1483,23 +1488,36 @@ namespace TBF
e.DisplayText = e.Item.SubItems[e.SubItem].Text;
e.Cancel = true;
}
#if STABLE_MASS_EXTRAS
if ((e.SubItem == (int)ParametersClmn.MassRepeats) &&
(!int.TryParse(e.DisplayText, out itmp) || itmp < 4 || itmp > 100))
{
e.DisplayText = e.Item.SubItems[e.SubItem].Text;
e.Cancel = true;
}
#if STABLE_MASS_EXTRAS
if ((e.SubItem == (int)ParametersClmn.MassSpread) && !Utils.TryParseUFloat(e.DisplayText, out powerPct))
{
e.DisplayText = e.Item.SubItems[e.SubItem].Text;
e.Cancel = true;
}
if ((e.SubItem == (int)ParametersClmn.MassMethod) && e.DisplayText != Strings.stable && e.DisplayText != Strings.fast)
if (e.SubItem == (int)ParametersClmn.MassMethod)
{
e.DisplayText = e.Item.SubItems[e.SubItem].Text;
e.Cancel = true;
bool mmIsOk = false;
for (MassMethod mm = 0; mm < MassMethod.Count; mm++)
{
if (mm.ToDescription().Equals(e.DisplayText))
{
mmIsOk = true;
break;
}
}
if (!mmIsOk)
{
e.DisplayText = e.Item.SubItems[e.SubItem].Text;
e.Cancel = true;
}
}
#endif
}