WMChart can plot error limits other then 2% and 5% and qp,qi style hyperbolic error limits, related DB and UI changes, ver. 2.33.2027

This commit is contained in:
Milan Hanajik 2023-03-20 10:14:29 +01:00
parent f0e57554f2
commit 7b95f5f436
17 changed files with 363 additions and 169 deletions

View File

@ -223,6 +223,14 @@ namespace Common
Count,
}
public enum FlowNames
{
QnQtQmin = 0,
Q3Q2Q1 = 1,
QpQi = 2,
Count,
}
public enum ProfileType
{
Q3R,

View File

@ -21,6 +21,18 @@ namespace Common
return (format == "F0") ? value.ToString("F0") : value.ToString(format).TrimEnd(new char[] { '0' });
}
public static FlowNames ProfileType2FlowNames(ProfileType pt)
{
switch (pt)
{
case ProfileType.Q3R: return FlowNames.Q3Q2Q1;
case ProfileType.QnClassColdWater: return FlowNames.QnQtQmin;
case ProfileType.QnClassHotWater: return FlowNames.QnQtQmin;
case ProfileType.QpQi: return FlowNames.QpQi;
default: return FlowNames.Q3Q2Q1;
}
}
public static string SignificantDigitsToFmt(double value, int sigDigits)
{
if (sigDigits == 6)

View File

@ -47,7 +47,7 @@ namespace Config.Entities
public virtual int AltProcPeriod { get; set; } /// Period of alternative procedures (0 = no alt. procedure)
public virtual float DN { get; set; } /// Not mapped to DB, valid in ProceduresCtrl for procedure filtering only
public virtual float Qn { get; set; } /// - ' ' -
public virtual double Qn { get; set; } /// - ' ' -
public virtual string MClass { get; set; } /// - ' ' -
public virtual string Producer { get; set; } /// - ' ' -

View File

@ -113,11 +113,13 @@ namespace Results.Entities
public virtual string Producer() { return WaterMeterData.Producer; }
public virtual string MetrologicalClass() { return WaterMeterData.MetrologicalClass; }
public virtual string ApprovalInfo() { return WaterMeterData.ApprovalInfo; }
public virtual bool NewQnames() { return WaterMeterData.NewQnames; }
public virtual FlowNames Qnames() { return (FlowNames)WaterMeterData.Qnames; }
public virtual double Q4_Qmax() { return WaterMeterData.Q4_Qmax; }
public virtual double Q3_Qn() { return WaterMeterData.Q3_Qn; }
public virtual double Q2_Qt() { return WaterMeterData.Q2_Qt; }
public virtual double Q1_Qmin() { return WaterMeterData.Q1_Qmin; }
public virtual double ErrLimHiQ() { return WaterMeterData.ErrLimHiQ; }
public virtual double ErrLimLoQ() { return WaterMeterData.ErrLimLoQ; }
public virtual bool Compound() { return WaterMeterData.Compound; }
public virtual bool HeatMeter() { return WaterMeterData.HeatMeter; }

View File

@ -17,11 +17,14 @@ namespace Results.Entities
public virtual double DN { get; set; } /// [mm]
public virtual double L { get; set; } /// [mm]
public virtual Mounting Mounting { get; set; } /// H / V / S / F
public virtual bool NewQnames { get; set; } /// Yes = Q3... No = Qn...
public virtual sbyte Qnames { get; set; } /// see Common.Enums.FlowNames
public virtual double Q4_Qmax { get; set; } /// [m3/h]
public virtual double Q3_Qn { get; set; } /// [m3/h]
public virtual double Q2_Qt { get; set; } /// [m3/h]
public virtual double Q1_Qmin { get; set; } /// [m3/h]
public virtual double ErrLimHiQ { get; set; } /// [%]
public virtual double ErrLimLoQ { get; set; } /// [%]
public virtual string MetrologicalClass { get; set; }
public virtual TemperatureClass TemperatureClass { get; set; }
public virtual PressureLossClass PressureLossClass { get; set; }
@ -66,11 +69,13 @@ namespace Results.Entities
DN = oriWMData.DN;
L = oriWMData.L;
Mounting = oriWMData.Mounting;
NewQnames = oriWMData.NewQnames;
Qnames = oriWMData.Qnames;
Q4_Qmax = oriWMData.Q4_Qmax;
Q3_Qn = oriWMData.Q3_Qn;
Q2_Qt = oriWMData.Q2_Qt;
Q1_Qmin = oriWMData.Q1_Qmin;
ErrLimHiQ = oriWMData.ErrLimHiQ;
ErrLimLoQ = oriWMData.ErrLimLoQ;
MetrologicalClass = oriWMData.MetrologicalClass;
TemperatureClass = oriWMData.TemperatureClass;
PressureLossClass = oriWMData.PressureLossClass;
@ -109,11 +114,13 @@ namespace Results.Entities
if (DN != wmd.DN) return false;
if (L != wmd.L) return false;
if (Mounting != wmd.Mounting) return false;
if (NewQnames != wmd.NewQnames) return false;
if (Qnames != wmd.Qnames) return false;
if (Q4_Qmax != wmd.Q4_Qmax) return false;
if (Q3_Qn != wmd.Q3_Qn) return false;
if (Q2_Qt != wmd.Q2_Qt) return false;
if (Q1_Qmin != wmd.Q1_Qmin) return false;
if (ErrLimHiQ != wmd.ErrLimHiQ) return false;
if (ErrLimLoQ != wmd.ErrLimLoQ) return false;
if (MetrologicalClass != wmd.MetrologicalClass) return false;
if (TemperatureClass != wmd.TemperatureClass) return false;
if (PressureLossClass != wmd.PressureLossClass) return false;
@ -167,11 +174,13 @@ namespace Results.Entities
writer.Write(DN);
writer.Write(L);
writer.Write((int)Mounting);
writer.Write(NewQnames);
writer.Write((int)Qnames);
writer.Write(Q4_Qmax);
writer.Write(Q3_Qn);
writer.Write(Q2_Qt);
writer.Write(Q1_Qmin);
writer.Write(ErrLimHiQ);
writer.Write(ErrLimLoQ);
writer.Write((MetrologicalClass != null) ? MetrologicalClass : string.Empty);
writer.Write((int)TemperatureClass);
writer.Write((int)PressureLossClass);
@ -205,11 +214,13 @@ namespace Results.Entities
DN = reader.ReadDouble();
L = reader.ReadDouble();
Mounting = (Mounting)reader.ReadInt32();
NewQnames = reader.ReadBoolean();
Qnames = (sbyte)reader.ReadInt32();
Q4_Qmax = reader.ReadDouble();
Q3_Qn = reader.ReadDouble();
Q2_Qt = reader.ReadDouble();
Q1_Qmin = reader.ReadDouble();
ErrLimHiQ = reader.ReadDouble();
ErrLimLoQ = reader.ReadDouble();
MetrologicalClass = reader.ReadString();
TemperatureClass = (TemperatureClass)reader.ReadInt32();
PressureLossClass = (PressureLossClass)reader.ReadInt32();

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2019 Sensus Slovensko a.s.
/// Copyright (c) 2019-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@ -14,6 +14,13 @@ namespace Results.Forms
{
public partial class MoreWMResultsDlg : Form
{
enum Tabs
{
Results = 0,
Graph,
Tracing,
}
public MoreWMResultsDlg(Results.Entities.WaterMeter wm, IList<ReferenceRecord> refRecords)
{
InitializeComponent();
@ -23,14 +30,15 @@ namespace Results.Forms
ShowAllResults(wm);
ShowChart(wm);
/// Select the initial tab page to be displayed
if (refRecords == null)
{
tabControl1.SelectTab(1);
tabControl1.TabPages.RemoveAt(2);
tabControl1.SelectTab((int)Tabs.Graph);
tabControl1.TabPages.RemoveAt((int)Tabs.Tracing);
}
else
{
tabControl1.SelectTab(2);
tabControl1.SelectTab((int)Tabs.Tracing);
ShowTracingResults(wm, refRecords);
}
}
@ -39,9 +47,9 @@ namespace Results.Forms
void Localize()
{
Text = Strings.Water_meter_results;
tabControl1.TabPages[0].Text = Strings.All_results;
tabControl1.TabPages[1].Text = Strings.Graphs;
tabControl1.TabPages[2].Text = Strings.Production_tracing_results;
tabControl1.TabPages[(int)Tabs.Results].Text = Strings.All_results;
tabControl1.TabPages[(int)Tabs.Graph].Text = Strings.Graphs;
tabControl1.TabPages[(int)Tabs.Tracing].Text = Strings.Production_tracing_results;
}
@ -107,11 +115,7 @@ namespace Results.Forms
void ShowChart(Results.Entities.WaterMeter wm)
{
//chart.ChartAreas[0].AxisX.LabelStyle.Format = "dd.MM.yy";
//chart.ChartAreas[0].AxisX.Interval = 1;
//chart.ChartAreas[0].AxisX.IntervalType = ;
tabControl1.TabPages[1].Controls.Add(Results.Output.WMChart.GetChart(wm, false));
tabControl1.TabPages[(int)Tabs.Graph].Controls.Add(Results.Output.WMChart.GetChart(wm, false));
}

View File

@ -18,13 +18,13 @@ namespace Results.Mappings
Map(x => x.L);
Map(x => x.Mounting);
#if MUNICH && LANG_DE
Map(x => x.NewQnames);
#endif
Map(x => x.Qnames);
Map(x => x.Q4_Qmax);
Map(x => x.Q3_Qn);
Map(x => x.Q2_Qt);
Map(x => x.Q1_Qmin);
Map(x => x.ErrLimHiQ);
Map(x => x.ErrLimLoQ);
Map(x => x.MetrologicalClass);
Map(x => x.TemperatureClass);

View File

@ -526,11 +526,11 @@ namespace Results.Output.Printers.Munich
}
lineNr++;
PrintAt(e, Tab1, lineNr * SpacingOne, wm.NewQnames() ? "Q3 :" : "Qn :");
PrintAt(e, Tab1, lineNr * SpacingOne, (wm.Qnames() == FlowNames.Q3Q2Q1) ? "Q3 :" : (wm.Qnames() == FlowNames.QpQi) ? "qp :" : "Qn :");
PrintAt(e, Tab2, lineNr * SpacingOne, wm.Q3_Qn().ToString());
if (compound)
{
PrintAt(e, Tab3, lineNr * SpacingOne, wm.NewQnames() ? "Q3 :" : "Qn :");
PrintAt(e, Tab3, lineNr * SpacingOne, (wm.Qnames() == FlowNames.Q3Q2Q1) ? "Q3 :" : (wm.Qnames() == FlowNames.QpQi) ? "qp :" : "Qn :");
PrintAt(e, Tab4, lineNr * SpacingOne, wm.Q3_Qn_Aux().ToString());
}
lineNr++;

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2019-2022 Sensus Metering Systems
/// Copyright (c) 2019-2023 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
@ -55,6 +55,9 @@ namespace Results.Output
chArea.AxisX.LogarithmBase = 10;
chArea.AxisX.IsLabelAutoFit = true;
Series upperLimit = new Series { Name = Strings.Upper_limit, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.Red };
Series lowerLimit = new Series { Name = Strings.Lower_limit, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.Red };
List<double> xs = new List<double>() { 0.0001, 0.0002, 0.0005,
0.001, 0.002, 0.005,
0.01, 0.02, 0.05,
@ -71,6 +74,8 @@ namespace Results.Output
double from = Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin);
double to = Units.ConvertTo(flowUnit, isQ4 ? wm.WaterMeterData.Q4_Qmax : wm.WaterMeterData.Q3_Qn);
bool inRange = false;
double qSharp = (wm.WaterMeterData.Qnames == (sbyte)FlowNames.QpQi) ? GetQsharp(wm, flowUnit) : 0;
double lastXs = 0;
for (int i = 0; i < xs.Count - 3; i += 3)
{
if (xs[i] <= from && from < xs[i + 3])
@ -88,6 +93,37 @@ namespace Results.Output
cl.FromPosition = Math.Log10(xs[j] * spacer);
cl.ToPosition = Math.Log10(xs[j] / spacer);
chArea.AxisX.CustomLabels.Add(cl);
if (wm.WaterMeterData.Qnames == (sbyte)FlowNames.QpQi)
{
if (lastXs != 0)
{
double insertedXs = Math.Sqrt(lastXs * xs[j]);
if (lastXs < qSharp && qSharp < insertedXs)
{
double errLim3 = GetErrorLimit(wm, flowUnit, qSharp);
lowerLimit.Points.AddXY(qSharp, -errLim3);
upperLimit.Points.AddXY(qSharp, +errLim3);
}
double errLim2 = GetErrorLimit(wm, flowUnit, insertedXs);
lowerLimit.Points.AddXY(insertedXs, -errLim2);
upperLimit.Points.AddXY(insertedXs, +errLim2);
if (insertedXs < qSharp && qSharp < xs[j])
{
double errLim3 = GetErrorLimit(wm, flowUnit, qSharp);
lowerLimit.Points.AddXY(qSharp, -errLim3);
upperLimit.Points.AddXY(qSharp, +errLim3);
}
}
lastXs = xs[j];
double errLim = GetErrorLimit(wm, flowUnit, xs[j]);
lowerLimit.Points.AddXY(xs[j], -errLim);
upperLimit.Points.AddXY(xs[j], +errLim);
}
}
}
@ -101,6 +137,36 @@ namespace Results.Output
cl.ToPosition = Math.Log10(xs[i + 3] / spacer);
chArea.AxisX.CustomLabels.Add(cl);
if (wm.WaterMeterData.Qnames == (sbyte)FlowNames.QpQi)
{
if (lastXs != 0)
{
double insertedXs = Math.Sqrt(lastXs * xs[i + 3]);
if (lastXs < qSharp && qSharp < insertedXs)
{
double errLim3 = GetErrorLimit(wm, flowUnit, qSharp);
lowerLimit.Points.AddXY(qSharp, -errLim3);
upperLimit.Points.AddXY(qSharp, +errLim3);
}
double errLim2 = GetErrorLimit(wm, flowUnit, insertedXs);
lowerLimit.Points.AddXY(insertedXs, -errLim2);
upperLimit.Points.AddXY(insertedXs, +errLim2);
if (insertedXs < qSharp && qSharp < xs[i + 3])
{
double errLim3 = GetErrorLimit(wm, flowUnit, qSharp);
lowerLimit.Points.AddXY(qSharp, -errLim3);
upperLimit.Points.AddXY(qSharp, +errLim3);
}
}
double errLim = GetErrorLimit(wm, flowUnit, xs[i + 3]);
lowerLimit.Points.AddXY(xs[i + 3], -errLim);
upperLimit.Points.AddXY(xs[i + 3], +errLim);
}
break;
}
}
@ -111,19 +177,20 @@ namespace Results.Output
Legend legend1 = new Legend { Name = "Legend1" };
Series upperLimit = new Series { Name = Strings.Upper_limit, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.Red };
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin), 5);
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), 5);
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), 2);
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q3_Qn), 2);
if (isQ4) upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q4_Qmax), 2);
if (wm.WaterMeterData.Qnames == (sbyte)FlowNames.Q3Q2Q1 || wm.WaterMeterData.Qnames == (sbyte)FlowNames.QnQtQmin)
{
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin), wm.WaterMeterData.ErrLimHiQ);
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), wm.WaterMeterData.ErrLimHiQ);
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), wm.WaterMeterData.ErrLimLoQ);
upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q3_Qn), wm.WaterMeterData.ErrLimLoQ);
if (isQ4) upperLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q4_Qmax), wm.WaterMeterData.ErrLimHiQ);
Series lowerLimit = new Series { Name = Strings.Lower_limit, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.Red };
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin), -5);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), -5);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), -2);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q3_Qn), -2);
if (isQ4) lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q4_Qmax), -2);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q1_Qmin), -wm.WaterMeterData.ErrLimHiQ);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), -wm.WaterMeterData.ErrLimHiQ);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q2_Qt), -wm.WaterMeterData.ErrLimLoQ);
lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q3_Qn), -wm.WaterMeterData.ErrLimLoQ);
if (isQ4) lowerLimit.Points.AddXY(Units.ConvertTo(flowUnit, wm.WaterMeterData.Q4_Qmax), -wm.WaterMeterData.ErrLimHiQ);
}
Series line = new Series { Name = Strings.Relative_error, ChartArea = "ChartArea1", ChartType = SeriesChartType.Line, Color = Color.DeepSkyBlue };
Series dots = new Series { Name = Strings.Relative_error + " ", ChartArea = "ChartArea1", ChartType = SeriesChartType.Point, Color = Color.RoyalBlue };
@ -137,12 +204,38 @@ namespace Results.Output
chart.ChartAreas.Add(chArea);
chart.Legends.Add(legend1);
chart.Series.Add(upperLimit);
chart.Series.Add(lowerLimit);
if (upperLimit.Points.Count > 1) chart.Series.Add(upperLimit);
if (lowerLimit.Points.Count > 1) chart.Series.Add(lowerLimit);
chart.Series.Add(dots);
chart.Series.Add(line);
return chart;
}
static double GetErrorLimit(WaterMeter wm, Unit flowUnit, double x)
{
double flow_m3 = Units.ConvertFrom(flowUnit, x);
switch (Convert.ToInt32(wm.WaterMeterData.Q2_Qt))
{
default:
case 1: return Math.Min(3.5, 1.0 + 0.01 * wm.WaterMeterData.Q3_Qn / flow_m3);
case 2: return Math.Min(5.0, 2.0 + 0.02 * wm.WaterMeterData.Q3_Qn / flow_m3);
case 3: return Math.Min(5.0, 3.0 + 0.05 * wm.WaterMeterData.Q3_Qn / flow_m3);
}
}
static double GetQsharp(WaterMeter wm, Unit flowUnit)
{
double qSharp;
switch (Convert.ToInt32(wm.WaterMeterData.Q2_Qt))
{
default:
case 1: qSharp = (0.01 / 2.5) * wm.WaterMeterData.Q3_Qn; break;
case 2: qSharp = (0.02 / 3.0) * wm.WaterMeterData.Q3_Qn; break;
case 3: qSharp = (0.05 / 2.0) * wm.WaterMeterData.Q3_Qn; break;
}
return Units.ConvertTo(flowUnit, qSharp);
}
}
}

View File

@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.32.2027.0")]
[assembly: AssemblyFileVersion("2.32.2027.0")]
[assembly: AssemblyVersion("2.33.2027.0")]
[assembly: AssemblyFileVersion("2.33.2027.0")]

View File

@ -1,8 +1,8 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
///
using TBF.Rig.Generic;
using Common;
using TBF.Rig.Generic;
namespace TBF.Rig.GenericDevices
{
@ -17,11 +17,13 @@ namespace TBF.Rig.GenericDevices
float L { get; } /// building length [mm]
Mounting Mounting { get; } /// mounting H / V
bool NewQnames { get; } /// true = Q3... false = Qn...
float Q4_Qmax { get; } /// [m3/h]
float Q3_Qn { get; } /// [m3/h]
float Q2_Qt { get; } /// [m3/h]
float Q1_Qmin { get; } /// [m3/h]
FlowNames Qnames { get; } /// true = Q3... false = Qn...
double Q4_Qmax { get; } /// [m3/h]
double Q3_Qn { get; } /// [m3/h]
double Q2_Qt { get; } /// [m3/h]
double Q1_Qmin { get; } /// [m3/h]
double ErrLimHiQ { get; } /// [%]
double ErrLimLoQ { get; } /// [%]
string MetrologicalClass { get; } /// R<Q3/Q1>
TemperatureClass TemperatureClass { get; } /// T30, T50, T70, ...

View File

@ -577,7 +577,7 @@ namespace TBF.Rig.Sequences
DN = WaterMeters[ix].DN,
Mounting = WaterMeters[ix].Mounting,
NewQnames = WaterMeters[ix].NewQnames,
Qnames = (sbyte)WaterMeters[ix].Qnames,
Q4_Qmax = WaterMeters[ix].Q4_Qmax,
Q3_Qn = WaterMeters[ix].Q3_Qn,
Q2_Qt = WaterMeters[ix].Q2_Qt,

View File

@ -55,20 +55,14 @@ namespace TBF.Rig.WaterMeters.Munich
"L [mm]",
Strings.Mounting,
Strings.New_Q_names,
Strings.Qn,
"Qn or Q3",
Strings.Metrological_class,
Strings.Approval_info,
};
public override string ParamName(int i)
{
string name = paramNames[i];
if (NewQnames && name.Equals(Strings.Qmax)) name = "Q4 [m3/h]";
if (NewQnames && name.Equals(Strings.Qn)) name = "Q3 [m3/h]";
if (NewQnames && name.Equals(Strings.Qt)) name = "Q2 [m3/h]";
if (NewQnames && name.Equals(Strings.Qmin)) name = "Q1 [m3/h]";
return name;
if (i == 7 && NewQnames) return NewQnames ? "Q3 [m3/h]" : "Qn [m3/h]";
return paramNames[i];
}
public override int ParamsCount() { return paramNames.Length; }

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2016 Sensus Metering Systems
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@ -34,11 +34,13 @@ namespace TBF.Rig.WaterMeters.Munich
public Mounting Mounting { get { return Mounting.NotSpecified; } }
/// <summary>Nominal water flow in [m3/h]</summary>
public bool NewQnames { get { return waterMeterCfg.ProcParams.NewQnames; } }
public float Q4_Qmax { get { return 0; } }
public float Q3_Qn { get { return waterMeterCfg.ProcParams.Qn; } }
public float Q2_Qt { get { return 0; } }
public float Q1_Qmin { get { return 0; } }
public FlowNames Qnames { get { return waterMeterCfg.ProcParams.NewQnames ? FlowNames.Q3Q2Q1 : FlowNames.QnQtQmin; } }
public double Q4_Qmax { get { return 0; } }
public double Q3_Qn { get { return waterMeterCfg.ProcParams.Qn; } }
public double Q2_Qt { get { return 0; } }
public double Q1_Qmin { get { return 0; } }
public double ErrLimHiQ { get { return 2.0; } }
public double ErrLimLoQ { get { return 5.0; } }
/// <summary>Metrological class, etc</summary>
public string MetrologicalClass { get { return waterMeterCfg.ProcParams.MetrologicalClass; } }

View File

@ -1,7 +1,8 @@
///
/// Copyright (c) 2013-2017 Sensus Metering Systems
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
@ -18,37 +19,39 @@ namespace TBF.Rig.WaterMeters.WaterMeter
public override XmlSerializer GetSerializer() { return Serializer; }
public string ProductName; /// Znak fabryczny (PL)
public string Producer; /// Producent (PL), Hersteller (D)
public string ProductName; /// 0 Znak fabryczny (PL)
public string Producer; /// 1 Producent (PL), Hersteller (D)
public float DN;
public float L; /// stavebná dĺžka [mm]
public Mounting Mounting;
public float DN; /// 2
public float L; /// 3 stavebná dĺžka [mm]
public Mounting Mounting; /// 4
public bool NewQnames; /// true = display Q4,Q3,Q2,Q1, false = display Qmax, Qn, Qt, Qmin
public float Qmax; /// [m3/h]
public float Qn; /// [m3/h]
public float Qt; /// [m3/h]
public float Qmin; /// [m3/h]
public FlowNames Qnames; /// 5 true = display Q4,Q3,Q2,Q1, false = display Qmax, Qn, Qt, Qmin
public double Qmax; /// 6 [m3/h]
public double Qn; /// 7 [m3/h]
public double Qt; /// 8 [m3/h]
public double Qmin; /// 9 [m3/h]
public double ErrLimHiQ; /// 10 [%]
public double ErrLimLoQ; /// 11 [%]
public string MetrologicalClass; /// Metr. Klasse
public TemperatureClass TemperatureClass;
public PressureLossClass PressureLossClass;
public MaxAdmissiblePressure MaxAdmissiblePressure;
public FlowProfileSensitivityClass FlowProfileSensitivityClass;
public string MetrologicalClass; /// 12 Metr. Klasse
public TemperatureClass TemperatureClass; /// 13
public PressureLossClass PressureLossClass; /// 14
public MaxAdmissiblePressure MaxAdmissiblePressure; /// 15
public FlowProfileSensitivityClass FlowProfileSensitivityClass; /// 16
public string ApprovalInfo; /// Zulassungszeichen, WE (PL)
public string Certificate;
public string ApprovalInfo; /// 17 Zulassungszeichen, WE (PL)
public string Certificate; /// 18
public double PulsesPerLtr; /// Target low limit of the flow increase or decrease
public double PulsesPerLtr; /// 19 Target low limit of the flow increase or decrease
public string Text1;
public string Text2;
public string Text3;
public string Text4;
public string Text5;
public string Text1; /// 20
public string Text2; /// 21
public string Text3; /// 22
public string Text4; /// 23
public string Text5; /// 24
public Medium WaterTemp; /// Woda: zimna / tepla (PL)
public Medium WaterTemp; /// 25 Woda: zimna / tepla (PL)
public override void InitializeAll()
@ -58,11 +61,13 @@ namespace TBF.Rig.WaterMeters.WaterMeter
DN = 0;
L = 0;
Mounting = Mounting.NotSpecified;
NewQnames = false;
Qmax = 4.0f;
Qn = 2.5f;
Qt = 0.005f;
Qmin = 0.003125f;
Qnames = FlowNames.Q3Q2Q1;
Qmax = 3.125;
Qn = 2.5;
Qt = 0.005;
Qmin = 0.003125;
ErrLimHiQ = 2.0;
ErrLimLoQ = 5.0;
MetrologicalClass = "A";
TemperatureClass = TemperatureClass.NotSpecified;
PressureLossClass = PressureLossClass.NotSpecified;
@ -76,7 +81,6 @@ namespace TBF.Rig.WaterMeters.WaterMeter
Text3 = string.Empty;
Text4 = string.Empty;
Text5 = string.Empty;
WaterTemp = Medium.ColdWater;
}
@ -87,11 +91,13 @@ namespace TBF.Rig.WaterMeters.WaterMeter
"DN",
Strings.L,
Strings.Mounting,
Strings.New_Q_names,
Strings.Qmax,
Strings.Qn,
Strings.Qt,
Strings.Qmin,
"Q desig.",
"Q4",
"Q3",
"Q2",
"Q1",
"Err.lim. Hi Q",
"Err.lim. Lo Q",
Strings.Metrological_class,
Strings.Temperature_class,
Strings.Pressure_loss_class,
@ -105,22 +111,67 @@ namespace TBF.Rig.WaterMeters.WaterMeter
"Text3",
"Text4",
"Text5",
Strings.Water, /// "Woda"
};
public override string ParamName(int i)
{
string name = paramNames[i];
switch (Qnames)
{
case FlowNames.Q3Q2Q1:
if (i == 6) return "Q4 [m3/h]";
if (i == 7) return "Q3 [m3/h]";
if (i == 8) return "Q2 [m3/h]";
if (i == 9) return "Q1 [m3/h]";
break;
case FlowNames.QnQtQmin:
if (i == 6) return "Qmax [m3/h]";
if (i == 7) return "Qn [m3/h]";
if (i == 8) return "Qt [m3/h]";
if (i == 9) return "Qmin [m3/h]";
break;
case FlowNames.QpQi:
if (i == 6) return "N/A";
if (i == 7) return "Qp [m3/h]";
if (i == 8) return "Qi [m3/h]";
if (i == 9) return "N/A";
break;
}
if (NewQnames && name.Equals(Strings.Qmax)) name = "Q4";
if (NewQnames && name.Equals(Strings.Qn)) name = "Q3";
if (NewQnames && name.Equals(Strings.Qt)) name = "Q2";
if (NewQnames && name.Equals(Strings.Qmin)) name = "Q1";
return name;
return paramNames[i];
}
public override int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int ix)
{
var values = new List<string>();
switch (ix)
{
case 4:
for (Mounting m = 0; m < Mounting.Count; m++) values.Add(m.ToDescription());
return values;
case 5:
for (FlowNames q = 0; q < FlowNames.Count; q++) values.Add(q.ToString());
return values;
case 13:
for (TemperatureClass tc = 0; tc < TemperatureClass.Count; tc++) values.Add(tc.ToDescription());
return values;
case 14:
for (PressureLossClass dp = 0; dp < PressureLossClass.Count; dp++) values.Add(dp.ToDescription());
return values;
case 15:
for (MaxAdmissiblePressure map = 0; map < MaxAdmissiblePressure.Count; map++) values.Add(map.ToDescription());
return values;
case 16:
for (FlowProfileSensitivityClass fps = 0; fps < FlowProfileSensitivityClass.Count; fps++) values.Add(fps.ToDescription());
return values;
case 25:
for (Medium m = 0; m < Medium.Count; m++) values.Add(m.ToDescription());
return values;
default:
return null;
}
}
public override string ToString(int i)
{
@ -131,26 +182,27 @@ namespace TBF.Rig.WaterMeters.WaterMeter
case 2: return DN.ToString();
case 3: return L.ToString();
case 4: return Mounting.ToDescription();
case 5: return (NewQnames ? Strings.yes : Strings.no);
case 5: return Qnames.ToString();
case 6: return Qmax.ToString();
case 7: return Qn.ToString();
case 8: return Qt.ToString();
case 9: return Qmin.ToString();
case 10: return MetrologicalClass;
case 11: return TemperatureClass.ToDescription();
case 12: return PressureLossClass.ToDescription();
case 13: return MaxAdmissiblePressure.ToDescription();
case 14: return FlowProfileSensitivityClass.ToDescription();
case 15: return ApprovalInfo;
case 16: return Certificate;
case 17: return PulsesPerLtr.ToString();
case 18: return Text1;
case 19: return Text2;
case 20: return Text3;
case 21: return Text4;
case 22: return Text5;
case 23: return (WaterTemp == Medium.HotWater) ? Medium.HotWater.ToDescription() : Medium.ColdWater.ToDescription(); /// "tepla" : "zimna";
case 10: return ErrLimHiQ.ToString();
case 11: return ErrLimLoQ.ToString();
case 12: return MetrologicalClass;
case 13: return TemperatureClass.ToDescription();
case 14: return PressureLossClass.ToDescription();
case 15: return MaxAdmissiblePressure.ToDescription();
case 16: return FlowProfileSensitivityClass.ToDescription();
case 17: return ApprovalInfo;
case 18: return Certificate;
case 19: return PulsesPerLtr.ToString();
case 20: return Text1;
case 21: return Text2;
case 22: return Text3;
case 23: return Text4;
case 24: return Text5;
case 25: return (WaterTemp == Medium.HotWater) ? Medium.HotWater.ToDescription() : Medium.ColdWater.ToDescription(); /// "tepla" : "zimna";
default: return string.Empty;
}
}
@ -169,46 +221,55 @@ namespace TBF.Rig.WaterMeters.WaterMeter
if (m.ToDescription().Equals(strValue)) { Mounting = m; return CfgUpdateFlags.None; }
}
break;
case 5: NewQnames = strValue.Equals(Strings.yes); return CfgUpdateFlags.None;
case 5:
for (FlowNames q = 0; q < FlowNames.Count; q++)
{
if (q.ToDescription().Equals(strValue)) { Qnames = q; return CfgUpdateFlags.None; }
}
break;
case 6: Qmax = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
case 7: Qn = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
case 8: Qt = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
case 9: Qmin = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
case 10: MetrologicalClass = strValue; return CfgUpdateFlags.None;
case 11:
case 12: MetrologicalClass = strValue; return CfgUpdateFlags.None;
case 13:
for (TemperatureClass tc = 0; tc < TemperatureClass.Count; tc++)
{
if (tc.ToDescription().Equals(strValue)) { TemperatureClass = tc; return CfgUpdateFlags.None; }
}
break;
case 12:
case 14:
for (PressureLossClass dp = 0; dp < PressureLossClass.Count; dp++)
{
if (dp.ToDescription().Equals(strValue)) { PressureLossClass = dp; return CfgUpdateFlags.None; }
}
break;
case 13:
case 15:
for (MaxAdmissiblePressure map = 0; map < MaxAdmissiblePressure.Count; map++)
{
if (map.ToDescription().Equals(strValue)) { MaxAdmissiblePressure = map; return CfgUpdateFlags.None; }
}
break;
case 14:
case 16:
for (FlowProfileSensitivityClass fps = 0; fps < FlowProfileSensitivityClass.Count; fps++)
{
if (fps.ToDescription().Equals(strValue)) { FlowProfileSensitivityClass = fps; return CfgUpdateFlags.None; }
}
break;
case 15: ApprovalInfo = strValue; return CfgUpdateFlags.None;
case 16: Certificate = strValue; return CfgUpdateFlags.None;
case 17: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 18: Text1 = strValue; return CfgUpdateFlags.None;
case 19: Text2 = strValue; return CfgUpdateFlags.None;
case 20: Text3 = strValue; return CfgUpdateFlags.None;
case 21: Text4 = strValue; return CfgUpdateFlags.None;
case 22: Text5 = strValue; return CfgUpdateFlags.None;
case 23: WaterTemp = strValue.Equals(Medium.HotWater.ToDescription()) ? Medium.HotWater : Medium.ColdWater; return CfgUpdateFlags.None; /// "tepla"
case 17: ApprovalInfo = strValue; return CfgUpdateFlags.None;
case 18: Certificate = strValue; return CfgUpdateFlags.None;
case 19: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 20: Text1 = strValue; return CfgUpdateFlags.None;
case 21: Text2 = strValue; return CfgUpdateFlags.None;
case 22: Text3 = strValue; return CfgUpdateFlags.None;
case 23: Text4 = strValue; return CfgUpdateFlags.None;
case 24: Text5 = strValue; return CfgUpdateFlags.None;
case 25:
for (Medium m = 0; m < Medium.Count; m++)
{
if (m.ToDescription().Equals(strValue)) { WaterTemp = m; return CfgUpdateFlags.None; }
}
break;
default: return CfgUpdateFlags.None;
}
@ -224,17 +285,19 @@ namespace TBF.Rig.WaterMeters.WaterMeter
{
case 0: /// ProductName
case 1: /// Producer
case 10: /// MetrologicalClass
case 15: /// ApprovalInfo
case 16: /// Certificate
case 18: /// Text1
case 19: /// Text2
case 20: /// Text3
case 21: /// Text4
case 22: /// Text5
case 12: /// MetrologicalClass
case 17: /// ApprovalInfo
case 18: /// Certificate
case 20: /// Text1
case 21: /// Text2
case 22: /// Text3
case 23: /// Text4
case 24: /// Text5
return true;
case 5:
if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true;
if (strValue.Equals(FlowNames.Q3Q2Q1.ToString()) ||
strValue.Equals(FlowNames.QnQtQmin.ToString()) ||
strValue.Equals(FlowNames.QpQi.ToString())) return true;
break;
case 2: /// DN
case 3: /// L
@ -242,25 +305,25 @@ namespace TBF.Rig.WaterMeters.WaterMeter
case 7: /// Qn
case 8: /// Qt
case 9: /// Qmin
case 17: /// PulsesPerLtr
case 19: /// PulsesPerLtr
if (Utils.TryParseUDouble(strValue, out dummy)) return true;
break;
case 4:
for (Mounting tc = 0; tc < Mounting.Count; tc++) if (tc.ToDescription().Equals(strValue)) return true;
break;
case 11:
case 13:
for (TemperatureClass tc = 0; tc < TemperatureClass.Count; tc++) if (tc.ToDescription().Equals(strValue)) return true;
break;
case 12:
case 14:
for (PressureLossClass tc = 0; tc < PressureLossClass.Count; tc++) if (tc.ToDescription().Equals(strValue)) return true;
break;
case 13:
case 15:
for (MaxAdmissiblePressure map = 0; map < MaxAdmissiblePressure.Count; map++) if (map.ToDescription().Equals(strValue)) return true;
break;
case 14:
case 16:
for (FlowProfileSensitivityClass tc = 0; tc < FlowProfileSensitivityClass.Count; tc++) if (tc.ToDescription().Equals(strValue)) return true;
break;
case 23:
case 25:
if (strValue.Equals(Medium.ColdWater.ToDescription()) || strValue.Equals(Medium.HotWater.ToDescription())) return true; /// "zimna", "tepla"
break;
default:
@ -279,11 +342,13 @@ namespace TBF.Rig.WaterMeters.WaterMeter
prms.DN = this.DN;
prms.L = this.L;
prms.Mounting = this.Mounting;
prms.NewQnames = this.NewQnames;
prms.Qnames = this.Qnames;
prms.Qmax = this.Qmax;
prms.Qn = this.Qn;
prms.Qt = this.Qt;
prms.Qmin = this.Qmin;
prms.ErrLimHiQ = this.ErrLimHiQ;
prms.ErrLimLoQ = this.ErrLimLoQ;
prms.MetrologicalClass = this.MetrologicalClass;
prms.TemperatureClass = this.TemperatureClass;
prms.PressureLossClass = this.PressureLossClass;
@ -297,7 +362,6 @@ namespace TBF.Rig.WaterMeters.WaterMeter
prms.Text3 = this.Text3;
prms.Text4 = this.Text4;
prms.Text5 = this.Text5;
prms.WaterTemp = this.WaterTemp;
}

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
///
using log4net;
using Common;
@ -31,11 +31,13 @@ namespace TBF.Rig.WaterMeters.WaterMeter
public Mounting Mounting { get { return waterMeterCfg.ProcParams.Mounting; } }
/// <summary>Nominal water flow in [m3/h]</summary>
public bool NewQnames { get { return waterMeterCfg.ProcParams.NewQnames; } }
public float Q4_Qmax { get { return waterMeterCfg.ProcParams.Qmax; } }
public float Q3_Qn { get { return waterMeterCfg.ProcParams.Qn; } }
public float Q2_Qt { get { return waterMeterCfg.ProcParams.Qt; } }
public float Q1_Qmin { get { return waterMeterCfg.ProcParams.Qmin; } }
public FlowNames Qnames { get { return waterMeterCfg.ProcParams.Qnames; } }
public double Q4_Qmax { get { return waterMeterCfg.ProcParams.Qmax; } }
public double Q3_Qn { get { return waterMeterCfg.ProcParams.Qn; } }
public double Q2_Qt { get { return waterMeterCfg.ProcParams.Qt; } }
public double Q1_Qmin { get { return waterMeterCfg.ProcParams.Qmin; } }
public double ErrLimHiQ { get { return waterMeterCfg.ProcParams.ErrLimHiQ; } }
public double ErrLimLoQ { get { return waterMeterCfg.ProcParams.ErrLimLoQ; } }
/// <summary>Metrological class, etc</summary>
public string MetrologicalClass { get { return waterMeterCfg.ProcParams.MetrologicalClass; } }

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2020-2022 Sensus Slovensko a.s.
/// Copyright (c) 2020-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@ -773,11 +773,11 @@ namespace TBF.UI.Procedures
TBF.Rig.WaterMeters.WaterMeter.ProcParams wmParams = waterMeterParams as TBF.Rig.WaterMeters.WaterMeter.ProcParams;
if (wmParams != null)
{
wmParams.NewQnames = (pt == ProfileType.Q3R);
wmParams.Qmax = (float)((pt == ProfileType.Manual) ? 0 : Formulas.GetQ4Qmax(dlg.Qn, dlg.MetroClass, medium));
wmParams.Qn = (float)dlg.Qn;
wmParams.Qt = (float)((pt == ProfileType.Manual) ? 0 : (pt == ProfileType.QpQi) ? (0.1 * dlg.Qn) : Formulas.GetQ2Qt(dlg.Qn, dlg.MetroClass, medium));
wmParams.Qmin = (float)((pt == ProfileType.Manual) ? 0 : (pt == ProfileType.QpQi) ? dlg.Qn / dlg.QpQiRatio : Formulas.GetQ1Qmin(dlg.Qn, dlg.MetroClass, medium));
wmParams.Qnames = Common.Utils.ProfileType2FlowNames(pt);
wmParams.Qmax = (pt == ProfileType.Manual) ? 0 : Formulas.GetQ4Qmax(dlg.Qn, dlg.MetroClass, medium);
wmParams.Qn = dlg.Qn;
wmParams.Qt = (pt == ProfileType.Manual) ? 0 : (pt == ProfileType.QpQi) ? (0.1 * dlg.Qn) : Formulas.GetQ2Qt(dlg.Qn, dlg.MetroClass, medium);
wmParams.Qmin = (pt == ProfileType.Manual) ? 0 : (pt == ProfileType.QpQi) ? dlg.Qn / dlg.QpQiRatio : Formulas.GetQ1Qmin(dlg.Qn, dlg.MetroClass, medium);
wmParams.MetrologicalClass = dlg.MetroClass;
wmParams.WaterTemp = medium;
}