diff --git a/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/Factory.cs b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/Factory.cs new file mode 100644 index 000000000..0ddc12566 --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/Factory.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Config.Entities; +using TBF.Rig.Generic; + +namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB +{ + public class Factory : IComponentFactory + { + public string ClassName { get { return GetType().Namespace.Substring(8); } } + + public override string ToString() { return ClassName; } + + public IComponent DummyComponent() { return new FrequencyRegisterReader(); } + + public IComponent GetComponent(IComponentCfg cfg, IList components) { return new FrequencyRegisterReader(cfg, components); } + + public IComponentCfg DefaultConfig() { return new RRCfg("Frequency", this); } + + public IComponentCfg CmpntCfgFromCmpntEntity(Component component) + { + return ComponentCfgBase.CreateFromDbEntity(RRCfg.Serializer, component, this); + } + } +} \ No newline at end of file diff --git a/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/FrequencyRegisterReader.cs b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/FrequencyRegisterReader.cs new file mode 100644 index 000000000..abca4984a --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/FrequencyRegisterReader.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using Common; +using log4net; +using TBF.Rig.GenericDevices; + +namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB +{ + public class FrequencyRegisterReader : ComponentBase, GenericDevices.IRegReader + { + private static readonly ILog log = LogManager.GetLogger(typeof(FrequencyRegisterReader)); + + public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); } + + readonly RRCfg rrCfg; + readonly TBF.Rig.ControlBoard.IControlBoard cb; + + public int Position { get{ return rrCfg.Position; } } + public Common.RegisterReaderType RegisterReaderType { get { return Common.RegisterReaderType.Pulses; } } + public double PulsesPerLtr { get { return rrCfg.ProcParams.PulsesPerLtr; } } + public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); ; } } + public int Filter { get { return rrCfg.ProcParams.Filter; } } + + public int WMPulses { get { return cb.PulsesWM(Position); } } + public int WMRefPulses { get { return cb.RefPulsesWM(Position); } } + public double WMVolume { get { return LtrsPerPulse * Convert.ToDouble(WMPulses); } } + + public double BeginWMState { get { return 0; } } /// Always 0 + public double EndWMState { get { return WMVolume; } } /// Derived from WMVolume + + + public FrequencyRegisterReader() { } + + public FrequencyRegisterReader(Generic.IComponentCfg cfg, IList components) + : base(cfg) + { + rrCfg = cfg as RRCfg; + + cb = TbfComponents.FindComponent(cfg.ParentName, components) as TBF.Rig.ControlBoard.IControlBoard; + if (cb == null) throw new Exception("Cannot find " + Name + " parent"); + + log.Warn(this.ToString()); + } + + public override void Initialize() { } + } +} \ No newline at end of file diff --git a/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfg.cs b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfg.cs new file mode 100644 index 000000000..130463d00 --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfg.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Xml.Serialization; +using Common; +using Config.Entities; +using TBF.Rig.Generic; + +namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB +{ + public class RRCfg : ComponentCfgBase, Generic.IChildComponentCfg + { + + public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RRCfg) })[0]; + public override XmlSerializer GetSerializer() { return Serializer; } + + IComponentCfgCtrl IComponentCfg.GetControl(IList cmpntEntities) { return new RRCfgCtrl(); } + + /// + /// Serialized parameters + /// + public int Position; /// 1..nrWaterMeters + + /// Procedure parameters + [XmlIgnore] + public RRProcParams ProcParams; + public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; } + public override IParamsProvider CreateProcParamsProvider() { return new RRProcParams(true); } + + /// Private parameterless constructor invoked by all other (public) constructors + RRCfg() + { + ProcParams = new RRProcParams(true); + } + + public RRCfg(string name, IComponentFactory factory) + : this() + { + Name = name; + Factory = factory; + ParentName = "UniCB"; + Position = 1; + } + + string IComponentCfg.ToString(int i) + { + return string.Format("Name={0}, Parent={1}, Position={2}", + Name, + (string.IsNullOrEmpty(ParentName) ? "-" : ParentName), + Position); + } + } +} \ No newline at end of file diff --git a/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.cs b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.cs new file mode 100644 index 000000000..3a08f3d94 --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.cs @@ -0,0 +1,106 @@ +/// +/// Copyright (c) 2021 Sensus Slovensko a.s. +/// +using System; +using System.Windows.Forms; +using Common; +using TBF.Rig.Generic; +using TBF.UI.Bench.Components; + +namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB +{ + public partial class RRCfgCtrl : UserControl, IComponentCfgCtrl + { + ComponentParametersDlg parent; + + bool IComponentCfgCtrl.ShowMore { get { return false; } } + + RRCfg config; + + IComponentCfg IComponentCfgCtrl.Config + { + get { return config as IComponentCfg; } + set + { + config = value as RRCfg; + Redraw(); + } + } + + public RRCfgCtrl() + { + InitializeComponent(); + } + + private void RegisterReaderCfgCtrl_Load(object sender, EventArgs e) + { + parent = ParentForm as ComponentParametersDlg; + if (parent == null) return; + + if (parent.CmpntEntities != null) + { + foreach (var cmpnt in parent.CmpntEntities) + { + if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is ControlBoard.Uni.Factory) + { + parentNameComboBox.Items.Add(cmpnt.Name); + } + } + } + + Redraw(); + } + + void IComponentCfgCtrl.Closing() + { + } + + void Redraw() + { + if (config == null) return; /// Control was not loaded, settings were not changed + + componentNameLabel.Text = config.Factory.ClassName; + nameTextBox.Text = config.Name; + parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName; + positionTextBox.Text = config.Position.ToString(); + } + + void IComponentCfgCtrl.Unlock() + { + nameTextBox.Enabled = true; + parentNameComboBox.Enabled = true; + positionTextBox.Enabled = true; + } + + CfgUpdateFlags IComponentCfgCtrl.VerifyCfg(ref string message) + { + CfgUpdateFlags flags = CfgUpdateFlags.None; + + int dummy; + if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text)) + { + flags |= CfgUpdateFlags.Error; + message += Environment.NewLine + "Invalid 'Parent Name'"; + } + if (!int.TryParse(positionTextBox.Text, out dummy) || (dummy < 1)) + { + flags |= CfgUpdateFlags.Error; + message += Environment.NewLine + "'Position' should be >= 1"; + } + return flags; + } + + CfgUpdateFlags IComponentCfgCtrl.UpdateCfg() + { + CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd; + + if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed + + config.Name = nameTextBox.Text; + config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text; + config.Position = int.Parse(positionTextBox.Text); + + return flags; + } + } +} diff --git a/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.designer.cs b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.designer.cs new file mode 100644 index 000000000..504914d46 --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.designer.cs @@ -0,0 +1,133 @@ +/// +/// Copyright (c) 2021 Sensus Slovensko a.s. +/// +namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB +{ + partial class RRCfgCtrl + { + /// + /// 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.positionTextBox = new System.Windows.Forms.TextBox(); + this.positionLabel = new System.Windows.Forms.Label(); + this.parentNameLabel = new System.Windows.Forms.Label(); + this.nameTextBox = new System.Windows.Forms.TextBox(); + this.nameLabel = new System.Windows.Forms.Label(); + this.componentNameLabel = new System.Windows.Forms.Label(); + this.parentNameComboBox = new System.Windows.Forms.ComboBox(); + this.SuspendLayout(); + // + // positionTextBox + // + this.positionTextBox.Enabled = false; + this.positionTextBox.Location = new System.Drawing.Point(136, 119); + this.positionTextBox.Name = "positionTextBox"; + this.positionTextBox.Size = new System.Drawing.Size(46, 20); + this.positionTextBox.TabIndex = 6; + // + // positionLabel + // + this.positionLabel.AutoSize = true; + this.positionLabel.Location = new System.Drawing.Point(26, 122); + this.positionLabel.Name = "positionLabel"; + this.positionLabel.Size = new System.Drawing.Size(44, 13); + this.positionLabel.TabIndex = 5; + this.positionLabel.Text = "Position"; + // + // parentNameLabel + // + this.parentNameLabel.AutoSize = true; + this.parentNameLabel.Location = new System.Drawing.Point(26, 96); + this.parentNameLabel.Name = "parentNameLabel"; + this.parentNameLabel.Size = new System.Drawing.Size(69, 13); + this.parentNameLabel.TabIndex = 3; + this.parentNameLabel.Text = "Parent Name"; + // + // nameTextBox + // + this.nameTextBox.Enabled = false; + this.nameTextBox.Location = new System.Drawing.Point(136, 67); + this.nameTextBox.Name = "nameTextBox"; + this.nameTextBox.Size = new System.Drawing.Size(130, 20); + this.nameTextBox.TabIndex = 2; + // + // nameLabel + // + this.nameLabel.AutoSize = true; + this.nameLabel.Location = new System.Drawing.Point(26, 70); + this.nameLabel.Name = "nameLabel"; + this.nameLabel.Size = new System.Drawing.Size(35, 13); + this.nameLabel.TabIndex = 1; + this.nameLabel.Text = "Name"; + // + // componentNameLabel + // + this.componentNameLabel.AutoSize = true; + this.componentNameLabel.Location = new System.Drawing.Point(133, 43); + this.componentNameLabel.Name = "componentNameLabel"; + this.componentNameLabel.Size = new System.Drawing.Size(83, 13); + this.componentNameLabel.TabIndex = 0; + this.componentNameLabel.Text = "ComonentName"; + // + // parentNameComboBox + // + this.parentNameComboBox.Enabled = false; + this.parentNameComboBox.FormattingEnabled = true; + this.parentNameComboBox.Location = new System.Drawing.Point(136, 93); + this.parentNameComboBox.Name = "parentNameComboBox"; + this.parentNameComboBox.Size = new System.Drawing.Size(130, 21); + this.parentNameComboBox.TabIndex = 4; + // + // RegisterReaderCfgCtrl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.parentNameComboBox); + this.Controls.Add(this.positionTextBox); + this.Controls.Add(this.positionLabel); + this.Controls.Add(this.parentNameLabel); + this.Controls.Add(this.nameTextBox); + this.Controls.Add(this.nameLabel); + this.Controls.Add(this.componentNameLabel); + this.Name = "RegisterReaderCfgCtrl"; + this.Size = new System.Drawing.Size(300, 200); + this.Load += new System.EventHandler(this.RegisterReaderCfgCtrl_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox positionTextBox; + private System.Windows.Forms.Label positionLabel; + private System.Windows.Forms.Label parentNameLabel; + private System.Windows.Forms.TextBox nameTextBox; + private System.Windows.Forms.Label nameLabel; + private System.Windows.Forms.Label componentNameLabel; + private System.Windows.Forms.ComboBox parentNameComboBox; + } +} diff --git a/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.resx b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRCfgCtrl.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/RegisterReaders/FrequencyMeterFromUniCB/RRProcParams.cs b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRProcParams.cs new file mode 100644 index 000000000..68f34de65 --- /dev/null +++ b/TBF/Rig/RegisterReaders/FrequencyMeterFromUniCB/RRProcParams.cs @@ -0,0 +1,132 @@ +/// +/// Copyright (c) 2021 Sensus Slovensko a.s. +/// +using System; +using System.IO; +using System.Text; +using System.Xml.Serialization; +using Common; +using Config.Entities; +using TBF.Rig.Generic; +using TBF.Resources; + +namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB +{ + public class RRProcParams : ProcedureParamsBase, IParamsProvider, IProcedureParams + { + public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RRProcParams) })[0]; + public override XmlSerializer GetSerializer() { return Serializer; } + + public double PulsesPerLtr; /// [l^-1] + public int Filter; + + public override void InitializeAll() + { + PulsesPerLtr = 1.0; + Filter = 0; + } + + string[] paramNames = new string[] + { + Strings.PulsesPerLtr, + Strings.Filter, + }; + 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 PulsesPerLtr.ToString(); + case 1: return Filter.ToString(); + default: return string.Empty; + } + } + + /// Retrieves parameters from UI controls + CfgUpdateFlags IParamsProvider.UpdateParam(int i, string strValue) + { + switch (i) + { + case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None; + case 1: Filter = int.Parse(strValue); return CfgUpdateFlags.None; + default: return CfgUpdateFlags.None; + } + } + + /// Verifies whether strings in UI controls represent valid parameters + bool IParamsProvider.ValidateParam(int i, string strValue, out string message) + { + message = string.Empty; + + double dummy; + int idummy; + switch (i) + { + case 0: + if (Utils.TryParseUDouble(strValue, out dummy)) return true; + break; + + case 1: + if (int.TryParse(strValue, out idummy) && (idummy >= 0)) return true; + break; + + default: + message = "Invalid index"; + return false; + } + + message = ParamName(i) + " is invalid"; + return false; + } + + void CopyContentTo(RRProcParams prms) + { + prms.PulsesPerLtr = this.PulsesPerLtr; + prms.Filter = this.Filter; + } + + IParamsProvider IParamsProvider.Clone() + { + RRProcParams pars = new RRProcParams(); + CopyContentTo(pars); + return pars; + } + + public override void UpdateFromDbEntity(ComponentProcedure dbEntity) + { + if (dbEntity == null) return; + try + { + RRProcParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as RRProcParams; + + procedureParamsEntity = dbEntity; + componentName = dbEntity.CmpntName; + procedure = dbEntity.Procedure; + + if (tmp != null) tmp.CopyContentTo(this); + } + catch + { + } + } + + + public RRProcParams() + { + } + + public RRProcParams(bool initialize) + { + if (initialize) InitializeAll(); + } + + public RRProcParams(ComponentProcedure procedureParamsEntity, string componentName, Procedure procedure) + { + this.procedureParamsEntity = procedureParamsEntity; + this.componentName = componentName; + this.procedure = procedure; + } + } +} diff --git a/TBF/Rig/TbfComponents.cs b/TBF/Rig/TbfComponents.cs index 0dc803513..b93a199a5 100644 --- a/TBF/Rig/TbfComponents.cs +++ b/TBF/Rig/TbfComponents.cs @@ -118,6 +118,7 @@ namespace TBF.Rig new BuiltIn.PumpTandem.PumpFactory(), new RegisterReaders.DataStream.MefImport.Factory(), /// 'Interface for data stream stream via MEF' new RegisterReaders.DataStream.Reader.Factory(), /// 'RegisterReader for data stream stream via MEF' + new RegisterReaders.FrequencyMeterFromUniCB.Factory(), /// new RegisterReaders.PulsesFromUniCB.Factory(), /// 'RegisterReader' new RegisterReaders.StandingStartStop.Factory(), /// 'RegisterReader for standing start/stop' new TestMethods.iPerlCommunication.iPerlHead.Factory(), /// 'RegisterReader for iPerl' diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj index 579bd0301..234db2393 100644 --- a/TBF/TBF.csproj +++ b/TBF/TBF.csproj @@ -1055,6 +1055,16 @@ WriterCfgCtrl.cs + + + + + UserControl + + + RRCfgCtrl.cs + + @@ -2856,6 +2866,9 @@ WriterCfgCtrl.cs + + RRCfgCtrl.cs + CycleBeginningForm.cs