/// /// Copyright (c) 2021 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Linq; using System.Xml.Serialization; using Common; using Config.Entities; using SchematicDrawing; using TBF.Rig.Generic; using TBF.Resources; using TBF.Tools; namespace TBF.Rig.Uni.FlowMeter { public class FlowMeterCfg : ComponentCfgBase, GenericDevices.ICalibRangesCfg, IChildComponentCfg, IParamsProvider, IDrawingItemWithMeasuredVal { public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlowMeterCfg) })[0]; public override XmlSerializer GetSerializer() { return Serializer; } public IComponentCfgCtrl GetControl(IList cmpntEntities) { var parents = cmpntEntities.Where(x => x.ClassName == "ControlBoard.Uni"); return new Configs.ParamsProvider.ComponentCfgCtrl(this, parents); } /// /// Serialized parameters /// public int Idx1; /// 0 /// 1..7, (DEWA300 : I1+I2=48, I1+I3=80, I2_I3=96, I1+I2+I3=112) public double NominalFlow; /// 1 /// Nominal flow in m3/h at nominal output frequency (typ. 2000 Hz) public double NominalFreq; /// 2 /// Nominal frequency in Hz (typ. 2000 Hz) public string MsrdFormat { get; set; } /// 3 public Unit MsrdUnit { get; set; } /// 4 public Unit TempUnit; /// 5 public Unit PressureUnit; /// 6 public bool Range1Enabled; /// 7 public double Temp1Lo; /// 8 public double Temp1Hi; /// 9 public double Press1Lo; /// 10 public double Press1Hi; /// 11 public bool Range2Enabled; /// 12 public double Temp2Lo; /// 13 public double Temp2Hi; /// 14 public double Press2Lo; /// 15 public double Press2Hi; /// 16 public bool Range3Enabled; /// 17 public double Temp3Lo; /// 18 public double Temp3Hi; /// 19 public double Press3Lo; /// 20 public double Press3Hi; /// 21 public bool Range4Enabled; /// 22 public double Temp4Lo; /// 23 public double Temp4Hi; /// 24 public double Press4Lo; /// 25 public double Press4Hi; /// 26 public bool Range5Enabled; /// 27 public double Temp5Lo; /// 28 public double Temp5Hi; /// 29 public double Press5Lo; /// 30 public double Press5Hi; /// 31 /// Calibration info serialized parameters displayed in Metrology tab page public string CalibCertificateNr; public string CalibCertificate1; public string CalibCertificate2; public string CalibCertificate3; public string CalibCertificate4; public string CalibCertificate5; public string CertPath; public string CertPath1; public string CertPath2; public string CertPath3; public string CertPath4; public string CertPath5; public DateTime CalibDate; public DateTime CalibDate1; public DateTime CalibDate2; public DateTime CalibDate3; public DateTime CalibDate4; public DateTime CalibDate5; public DateTime CalibValidDate; public DateTime CalibValidDate1; public DateTime CalibValidDate2; public DateTime CalibValidDate3; public DateTime CalibValidDate4; public DateTime CalibValidDate5; /// Schematic drawing info public Shape Shape { get; set; } public int X { get; set; } public int Y { get; set; } public Sz Sz { get; set; } public Orient Orient { get; set; } public bool Flip { get; set; } public int LblX { get; set; } public int LblY { get; set; } public Orient LblOrient { get; set; } public int MsrdX { get; set; } public int MsrdY { get; set; } public Orient MsrdOrient { get; set; } [XmlIgnore] public IList GNodes { get; set; } [XmlIgnore] public double MsrdValLimLo { get { return msrdValLimLo; } set { msrdValLimLo = value; } } /// in [m3/h] [XmlIgnore] public double MsrdValLimHi { get { return msrdValLimHi; } set { msrdValLimHi = value; } } /// in [m3/h] double msrdValLimLo = 0; /// in [m3/h] double msrdValLimHi; /// in [m3/h] [XmlIgnore] public bool IsOffline { get; set; } public bool RangeEnabled(int rangeIx1) { switch (rangeIx1) { default: case 0: return !(Range1Enabled || Range2Enabled || Range3Enabled || Range4Enabled || Range5Enabled); case 1: return Range1Enabled; case 2: return Range2Enabled; case 3: return Range3Enabled; case 4: return Range4Enabled; case 5: return Range5Enabled; } } public double GetTempLo(int rangeIx1) { switch (rangeIx1) { default: case 0: return 5.0; /// °C case 1: return Temp1Lo; case 2: return Temp2Lo; case 3: return Temp3Lo; case 4: return Temp4Lo; case 5: return Temp5Lo; } } public double GetTempHi(int rangeIx1) { switch (rangeIx1) { default: case 0: return 95.0; /// °C case 1: return Temp1Hi; case 2: return Temp2Hi; case 3: return Temp3Hi; case 4: return Temp4Hi; case 5: return Temp5Hi; } } public double GetPressLo(int rangeIx1) { switch (rangeIx1) { default: case 0: return 0; /// bar case 1: return Press1Lo; case 2: return Press2Lo; case 3: return Press3Lo; case 4: return Press4Lo; case 5: return Press5Lo; } } public double GetPressHi(int rangeIx1) { switch (rangeIx1) { default: case 0: return 16.0; /// bar case 1: return Press1Hi; case 2: return Press2Hi; case 3: return Press3Hi; case 4: return Press4Hi; case 5: return Press5Hi; } } public string GetCalibCertificate(int rangeIx1) { switch (rangeIx1) { default: case 0: return CalibCertificateNr; case 1: return CalibCertificate1; case 2: return CalibCertificate2; case 3: return CalibCertificate3; case 4: return CalibCertificate4; case 5: return CalibCertificate5; } } public void SetCalibCertificate(int rangeIx1, string certificate) { switch (rangeIx1) { default: case 0: CalibCertificateNr = certificate; return; case 1: CalibCertificate1 = certificate; return; case 2: CalibCertificate2 = certificate; return; case 3: CalibCertificate3 = certificate; return; case 4: CalibCertificate4 = certificate; return; case 5: CalibCertificate5 = certificate; return; } } public string GetCertPath(int rangeIx1) { switch (rangeIx1) { default: case 0: return CertPath; case 1: return CertPath1; case 2: return CertPath2; case 3: return CertPath3; case 4: return CertPath4; case 5: return CertPath5; } } public void SetCertPath(int rangeIx1, string certificate) { switch (rangeIx1) { default: case 0: CertPath = certificate; return; case 1: CertPath1 = certificate; return; case 2: CertPath2 = certificate; return; case 3: CertPath3 = certificate; return; case 4: CertPath4 = certificate; return; case 5: CertPath5 = certificate; return; } } public DateTime GetCalibDate(int rangeIx1) { switch (rangeIx1) { default: case 0: return CalibDate; case 1: return CalibDate1; case 2: return CalibDate2; case 3: return CalibDate3; case 4: return CalibDate4; case 5: return CalibDate5; } } public void SetCalibDate(int rangeIx1, DateTime calibDate) { switch (rangeIx1) { default: case 0: CalibDate = calibDate; return; case 1: CalibDate1 = calibDate; return; case 2: CalibDate2 = calibDate; return; case 3: CalibDate3 = calibDate; return; case 4: CalibDate4 = calibDate; return; case 5: CalibDate5 = calibDate; return; } } public DateTime GetCalibValidDate(int rangeIx1) { switch (rangeIx1) { default: case 0: return CalibValidDate; case 1: return CalibValidDate1; case 2: return CalibValidDate2; case 3: return CalibValidDate3; case 4: return CalibValidDate4; case 5: return CalibValidDate5; } } public void SetCalibValidDate(int rangeIx1, DateTime calibValidDate) { switch (rangeIx1) { default: case 0: CalibValidDate = calibValidDate; return; case 1: CalibValidDate1 = calibValidDate; return; case 2: CalibValidDate2 = calibValidDate; return; case 3: CalibValidDate3 = calibValidDate; return; case 4: CalibValidDate4 = calibValidDate; return; case 5: CalibValidDate5 = calibValidDate; return; } } /// Private parameterless constructor invoked by all other (public) constructors FlowMeterCfg() { GNodes = new List(); } public FlowMeterCfg(IComponentFactory factory, string name) : this() { Shape = Shape.FlowM; Sz = Sz.M; Factory = factory; Name = name; ParentName = "UniCB"; InitializeAll(); } public string ComponentName { get { return Name; } } public void InitializeAll() { Idx1 = 1; NominalFlow = 1; NominalFreq = 2000; MsrdFormat = "{0:F3} m3/h"; MsrdUnit = Unit.m3ph; MsrdValLimLo = 0; MsrdValLimHi = NominalFlow; TempUnit = Unit.C; PressureUnit = Unit.bar; Range1Enabled = false; Temp1Lo = 15; Temp1Hi = 25; Press1Lo = 0; Press1Hi = 16; Range2Enabled = false; Temp2Lo = 15; Temp2Hi = 25; Press2Lo = 0; Press2Hi = 16; Range3Enabled = false; Temp3Lo = 15; Temp3Hi = 25; Press3Lo = 0; Press3Hi = 16; Range4Enabled = false; Temp4Lo = 15; Temp4Hi = 25; Press4Lo = 0; Press4Hi = 16; Range5Enabled = false; Temp5Lo = 15; Temp5Hi = 25; Press5Lo = 0; Press5Hi = 16; LblX = 38; MsrdX = 38; MsrdY = 22; } string[] paramNames = new string[] { "Identification number (1 .. 7)", /// 0 "Nominal flow [m3/h]", /// 1 "Nominal frequency [Hz]", /// 2 "Display format", /// 3 "Unit of flow on a display", /// 4 "Unit of temperature", /// 5 "Unit of pressure", /// 6 "Range 1 enabled", /// 7 "Range 1 : Temperature Lo", /// 8 "Range 1 : Temperature Hi", /// 9 "Range 1 : Pressure Lo", /// 10 "Range 1 : Pressure Hi", /// 11 "Range 2 enabled", /// 12 "Range 2 : Temperature Lo", "Range 2 : Temperature Hi", "Range 2 : Pressure Lo", "Range 2 : Pressure Hi", "Range 3 enabled", "Range 3 : Temperature Lo", "Range 3 : Temperature Hi", "Range 3 : Pressure Lo", "Range 3 : Pressure Hi", "Range 4 enabled", "Range 4 : Temperature Lo", "Range 4 : Temperature Hi", "Range 4 : Pressure Lo", "Range 4 : Pressure Hi", "Range 5 enabled", "Range 5 : Temperature Lo", "Range 5 : Temperature Hi", "Range 5 : Pressure Lo", "Range 5 : Pressure Hi", }; public string ParamName(int i) { return paramNames[i]; } public int ParamsCount() { return paramNames.Length; } public ICollection ParamValues(int i) { switch (i) { case 0: return new string[] { "1", "2", "3", "4", "5", "6", "7" }; case 4: return new string[] { "m3/h", "l/h", "gal/m" }; case 5: return new string[] { "°C", "°F", "K" }; case 6: return new string[] { "Pa", "hPa", "mbar", "kPa", "inHg", "psi", "bar", "MPa" }; case 7: case 12: case 17: case 22: case 27: return new string[] { Strings.yes, Strings.no }; default: return null; } } public string ToString(int i) { switch (i) { case 0: return Idx1.ToString(); case 1: return NominalFlow.ToString(); case 2: return NominalFreq.ToString(); case 3: return MsrdFormat; case 4: return MsrdUnit.ToDescription(); case 5: return TempUnit.ToDescription(); case 6: return PressureUnit.ToDescription(); case 7: return Range1Enabled ? Strings.yes : Strings.no; case 8: return Temp1Lo.ToString(); case 9: return Temp1Hi.ToString(); case 10: return Press1Lo.ToString(); case 11: return Press1Hi.ToString(); case 12: return Range2Enabled ? Strings.yes : Strings.no; case 13: return Temp2Lo.ToString(); case 14: return Temp2Hi.ToString(); case 15: return Press2Lo.ToString(); case 16: return Press2Hi.ToString(); case 17: return Range3Enabled ? Strings.yes : Strings.no; case 18: return Temp3Lo.ToString(); case 19: return Temp3Hi.ToString(); case 20: return Press3Lo.ToString(); case 21: return Press3Hi.ToString(); case 22: return Range4Enabled ? Strings.yes : Strings.no; case 23: return Temp4Lo.ToString(); case 24: return Temp4Hi.ToString(); case 25: return Press4Lo.ToString(); case 26: return Press4Hi.ToString(); case 27: return Range5Enabled ? Strings.yes : Strings.no; case 28: return Temp5Lo.ToString(); case 29: return Temp5Hi.ToString(); case 30: return Press5Lo.ToString(); case 31: return Press5Hi.ToString(); default: return string.Format("{0}({1}) {2}[{3},{4}] Idx1={5}, NominalFlow={6}", Name, (string.IsNullOrEmpty(ParentName) ? "-" : ParentName), Shape, X, Y, Idx1, NominalFlow); } } public CfgUpdateFlags UpdateParam(int i, string str) { switch (i) { case 0: Idx1 = int.Parse(str); return CfgUpdateFlags.RestartRqrd; case 1: NominalFlow = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 2: NominalFreq = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 3: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd; //case 4: MsrdUnit = (str == "l/h") ? Unit.lph : Unit.m3ph; return CfgUpdateFlags.RestartRqrd; case 4: MsrdUnit = ParseFlowUnit(str); return CfgUpdateFlags.RestartRqrd; case 5: TempUnit.ToDescription(); return CfgUpdateFlags.RestartRqrd; case 6: PressureUnit.ToDescription(); return CfgUpdateFlags.RestartRqrd; case 7: Range1Enabled = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd; case 8: Temp1Lo = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 9: Temp1Hi = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 10: Press1Lo = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 11: Press1Hi = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 12: Range2Enabled = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd; case 13: Temp2Lo = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 14: Temp2Hi = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 15: Press2Lo = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 16: Press2Hi = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 17: Range3Enabled = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd; case 18: Temp3Lo = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 19: Temp3Hi = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 20: Press3Lo = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 21: Press3Hi = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 22: Range4Enabled = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd; case 23: Temp4Lo = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 24: Temp4Hi = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 25: Press4Lo = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 26: Press4Hi = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 27: Range5Enabled = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd; case 28: Temp5Lo = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 29: Temp5Hi = TBF.Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd; case 30: Press5Lo = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; case 31: Press5Hi = TBF.Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd; default: return CfgUpdateFlags.None; } } public bool ValidateParam(int i, string str, out string message) { message = string.Empty; int idummy; double dummy; switch (i) { case 0: if (int.TryParse(str, out idummy) && idummy >= 1 && idummy <= 7) return true; break; case 1: case 2: case 10: case 11: case 15: case 16: case 20: case 21: case 25: case 26: case 30: case 31: if (TBF.Utils.TryParseUDouble(str, out dummy)) return true; break; case 8: case 9: case 13: case 14: case 18: case 19: case 23: case 24: case 28: case 29: if (TBF.Utils.TryParseSDouble(str, out dummy)) return true; break; case 3: return true; case 4: case 5: case 6: case 7: case 12: case 17: case 22: case 27: if (ParamValues(i).Contains(str)) return true; break; default: message = "Invalid index"; return false; } message = ParamName(i) + " is invalid"; return false; } void CopyContentTo(FlowMeterCfg prms) { prms.ParentName = ParentName; prms.Idx1 = Idx1; prms.NominalFlow = NominalFlow; prms.NominalFreq = NominalFreq; prms.MsrdFormat = MsrdFormat; prms.MsrdUnit = MsrdUnit; prms.TempUnit = TempUnit; prms.PressureUnit = PressureUnit; prms.Range1Enabled = Range1Enabled; prms.Temp1Lo = Temp1Lo; prms.Temp1Hi = Temp1Hi; prms.Press1Lo = Press1Lo; prms.Press1Hi = Press1Hi; prms.Range2Enabled = Range2Enabled; prms.Temp2Lo = Temp2Lo; prms.Temp2Hi = Temp2Hi; prms.Press2Lo = Press2Lo; prms.Press2Hi = Press2Hi; prms.Range3Enabled = Range3Enabled; prms.Temp3Lo = Temp3Lo; prms.Temp3Hi = Temp3Hi; prms.Press3Lo = Press3Lo; prms.Press3Hi = Press3Hi; prms.Range4Enabled = Range4Enabled; prms.Temp4Lo = Temp4Lo; prms.Temp4Hi = Temp4Hi; prms.Press4Lo = Press4Lo; prms.Press4Hi = Press4Hi; prms.Range5Enabled = Range5Enabled; prms.Temp5Lo = Temp5Lo; prms.Temp5Hi = Temp5Hi; prms.Press5Lo = Press5Lo; prms.Press5Hi = Press5Hi; } public IParamsProvider Clone() { FlowMeterCfg pars = new FlowMeterCfg(); CopyContentTo(pars); return pars; } public bool UpdateEmbeddedDbEntity() { return true; /// =OK, do nothing } public static Unit ParseFlowUnit(string str) { //Check if the string is a valid unit description Unit fromDescription = Units.FromDescription(str); if (fromDescription != Unit.None) return fromDescription; //check if the string is a valid unit name switch (str) { case "l/h": return Unit.lph; case "gal/m": return Unit.USgalpm; case "m3/h": default: return Unit.m3ph; } } } }