Refactorization : BenchControl -> Rig

This commit is contained in:
Milan Hanajik
2021-03-05 16:12:24 +01:00
parent 84c8ec26b6
commit 6cf3bd6160
1461 changed files with 6330 additions and 6330 deletions
+61
View File
@@ -0,0 +1,61 @@
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using Dirichlet.Numerics;
using log4net;
using TBF.Rig.ControlBoard;
namespace TBF.Rig.BuiltIn.Pump
{
public class Pump : ComponentBase, GenericDevices.IPump, GenericDevices.IValve, SchematicDrawing.IDrawingItCmpnt
{
private static readonly ILog log = LogManager.GetLogger(typeof(Pump));
public override string ToString() { return string.Format("Pump({0})", Cfg.ToString(1)); }
readonly PumpCfg pumpCfg;
public SchematicDrawing.IDrawingItem DrawingItem { get { return pumpCfg as SchematicDrawing.IDrawingItem; } }
public int Delay { get { return pumpCfg.Delay; } }
public ValveCategory Category { get { return ValveCategory.Feeding; } } /// Pump category is Feeding
public GenericDevices.IValve CoupledTo { get { return null; } }
public bool InvertCouple { get { return false; } }
public int LagOpening { get { return 0; } }
public int LagClosing { get { return 0; } }
public double Power { get { return State ? 100.0 : 0; } }
readonly IControlBoard controlBoard;
readonly int bitPosition; /// 0 .. 127
public readonly UInt128 Mask; /// derived from bitPosition in the constructor
public Pump()
{
}
public Pump(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
pumpCfg = cfg as PumpCfg;
controlBoard = TbfComponents.FindComponent(cfg.ParentName, components) as IControlBoard;
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
bitPosition = pumpCfg.BitNr;
Mask = (((UInt128)1) << pumpCfg.BitNr);
log.Warn(this.ToString());
}
public bool State
{
get { return (controlBoard.Route & Mask) != 0; }
}
}
}
+72
View File
@@ -0,0 +1,72 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using System.Xml.Serialization;
using SchematicDrawing;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.Pump
{
public class PumpCfg : ComponentCfgBase, IChildComponentCfg, IRouteBasedDrawingItem
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PumpCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new PumpCfgCtrl(); }
///
/// Serialized parameters
///
public int BitNr { get; set; }
public bool Inverted { get; set; } /// When true the pump function is inverted: 0 = on, 1 = off
public int Delay;
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; }
[XmlIgnore]
public IList<GNode> GNodes { get; set; }
[XmlIgnore]
public IList<GEdge> EdgesToSet { get; set; }
/// Private parameterless constructor invoked by all other (public) constructors
PumpCfg()
{
GNodes = new List<GNode>();
EdgesToSet = new List<GEdge>();
}
public PumpCfg(IComponentFactory factory)
: this()
{
Shape = Shape.Pump;
Sz = Sz.M;
Factory = factory;
Name = "P";
ParentName = "CB";
BitNr = 0;
Delay = 1;
}
public string ToString(int i)
{
return string.Format("Name={0}, Parent={1}, Bit={2}, Delay={3}",
Name,
(string.IsNullOrEmpty(ParentName) ? "-" : ParentName),
BitNr,
Delay);
}
}
}
+156
View File
@@ -0,0 +1,156 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
namespace TBF.Rig.BuiltIn.Pump
{
partial class PumpCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.bitPositionTextBox = new System.Windows.Forms.TextBox();
this.bitPositionLabel = 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.classNameLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.delayTextBox = new System.Windows.Forms.TextBox();
this.delayLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// bitPositionTextBox
//
this.bitPositionTextBox.Enabled = false;
this.bitPositionTextBox.Location = new System.Drawing.Point(122, 99);
this.bitPositionTextBox.Name = "bitPositionTextBox";
this.bitPositionTextBox.Size = new System.Drawing.Size(46, 20);
this.bitPositionTextBox.TabIndex = 6;
//
// bitPositionLabel
//
this.bitPositionLabel.AutoSize = true;
this.bitPositionLabel.Location = new System.Drawing.Point(36, 102);
this.bitPositionLabel.Name = "bitPositionLabel";
this.bitPositionLabel.Size = new System.Drawing.Size(59, 13);
this.bitPositionLabel.TabIndex = 5;
this.bitPositionLabel.Text = "Bit Position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(36, 76);
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(122, 47);
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(36, 50);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(119, 21);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(122, 73);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// delayTextBox
//
this.delayTextBox.Enabled = false;
this.delayTextBox.Location = new System.Drawing.Point(122, 124);
this.delayTextBox.Name = "delayTextBox";
this.delayTextBox.Size = new System.Drawing.Size(46, 20);
this.delayTextBox.TabIndex = 8;
//
// delayLabel
//
this.delayLabel.AutoSize = true;
this.delayLabel.Location = new System.Drawing.Point(36, 127);
this.delayLabel.Name = "delayLabel";
this.delayLabel.Size = new System.Drawing.Size(48, 13);
this.delayLabel.TabIndex = 7;
this.delayLabel.Text = "Delay [s]";
//
// PumpCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.delayTextBox);
this.Controls.Add(this.delayLabel);
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.bitPositionTextBox);
this.Controls.Add(this.bitPositionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "PumpCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox bitPositionTextBox;
private System.Windows.Forms.Label bitPositionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
private System.Windows.Forms.TextBox delayTextBox;
private System.Windows.Forms.Label delayLabel;
}
}
+113
View File
@@ -0,0 +1,113 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
using System;
using System.Windows.Forms;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
namespace TBF.Rig.BuiltIn.Pump
{
public partial class PumpCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
public bool ShowMore { get { return false; } }
PumpCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as PumpCfg;
Redraw();
}
}
public PumpCfgCtrl()
{
InitializeComponent();
}
private void PumpCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.CmpntEntities != null)
{
foreach (var cmpnt in parent.CmpntEntities)
{
if (cmpnt.ClassName.Contains("ControlBoard"))
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
bitPositionTextBox.Text = config.BitNr.ToString();
delayTextBox.Text = config.Delay.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
bitPositionTextBox.Enabled = true;
delayTextBox.Enabled = true;
}
public CfgUpdateFlags 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.BitNr = int.Parse(bitPositionTextBox.Text);
config.Delay = int.Parse(delayTextBox.Text);
return flags;
}
public CfgUpdateFlags 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(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 128)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 127";
}
if (!int.TryParse(delayTextBox.Text, out dummy) || dummy < 0 || dummy >= 300 || (dummy % StateMachine.Period) != 0)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Delay' should be between 0 and 300s (5min)";
}
return flags;
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+27
View File
@@ -0,0 +1,27 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.Pump
{
public class PumpFactory : IComponentFactory
{
public string ClassName { get { return "Pump"; } }
public override string ToString() { return ClassName; }
public void ResetStaticProperties() { Pump.ResetStaticProperties(); }
public IComponent DummyComponent() { return new Pump(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Pump(cfg, components); }
public IComponentCfg DefaultConfig() { return new PumpCfg(this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(PumpCfg.Serializer, component, this);
}
}
}
+179
View File
@@ -0,0 +1,179 @@
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using Dirichlet.Numerics;
using log4net;
using TBF.Rig.ControlBoard.Legacy;
namespace TBF.Rig.BuiltIn.PumpTandem
{
public class Pump : ComponentBase, GenericDevices.IPumpFM, GenericDevices.IValve, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(Pump));
public override string ToString() { return string.Format("PumpTandem({0})", Cfg.ToString(1)); }
readonly PumpCfg pumpCfg;
readonly GenericDevices.IPump pump1;
readonly GenericDevices.IPump pump2;
readonly GenericDevices.IPumpFM pumpFm1;
readonly GenericDevices.IPumpFM pumpFm2;
public bool State { get { return pump1.State || pump2.State; } }
public int Delay { get { return Math.Max(pump1.Delay, pump2.Delay); } }
public ValveCategory Category { get { return ValveCategory.Feeding; } } /// Pump category is Feeding
public GenericDevices.IValve CoupledTo { get { return null; } }
public bool InvertCouple { get { return false; } }
public int LagOpening { get { return 0; } }
public int LagClosing { get { return 0; } }
/// <summary>
/// Pump power in [%] in range 0 .. 100.0
/// </summary>
public double Power
{
get { return (pump1.Power + pump2.Power) / 2; }
}
readonly UInt128 mask1;
readonly UInt128 mask2;
public UInt128 Mask { get { return mask1 | mask2; } } /// derived from masks of two pumps
public Pump()
{
}
public Pump(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
pumpCfg = cfg as PumpCfg;
pump1 = (GenericDevices.IPump)TbfComponents.FindComponent(pumpCfg.Pump1, components);
if (pump1 == null) throw new Exception("Cannot find component Pump 1");
pump2 = (GenericDevices.IPump)TbfComponents.FindComponent(pumpCfg.Pump2, components);
if (pump2 == null) throw new Exception("Cannot find component Pump 2");
pumpFm1 = pump1 as GenericDevices.IPumpFM;
pumpFm2 = pump2 as GenericDevices.IPumpFM;
if (pump1 is BuiltIn.Pump.Pump) { mask1 = (pump1 as BuiltIn.Pump.Pump).Mask; }
else if (pump1 is Elde.PumpWithFM.Pump) { mask1 = (pump1 as Elde.PumpWithFM.Pump).Mask; }
else if (pump1 is Danfoss.VLT2800.Pump) { mask1 = (pump1 as Danfoss.VLT2800.Pump).Mask; }
else { mask1 = 0; }
if (pump2 is BuiltIn.Pump.Pump) { mask2 = (pump2 as BuiltIn.Pump.Pump).Mask; }
else if (pump2 is Elde.PumpWithFM.Pump) { mask2 = (pump2 as Elde.PumpWithFM.Pump).Mask; }
else if (pump2 is Danfoss.VLT2800.Pump) { mask2 = (pump2 as Danfoss.VLT2800.Pump).Mask; }
else { mask2 = 0; }
log.Warn(this.ToString());
}
public void TurnOn(double powerArg)
{
if ((pumpFm1 != null) && (pumpFm2 != null))
{
pumpFm1.TurnOn(powerArg);
pumpFm2.TurnOn(powerArg);
}
else if ((pumpFm1 != null) && (pumpFm2 == null))
{
// TODO
if (powerArg >= 50)
{
pumpFm1.TurnOn(2 * (powerArg - 50.0));
//pump2.
}
else
{
pumpFm1.TurnOn(2 * powerArg);
//pump2.
}
// TODO
}
}
public void TurnOff()
{
if ((pumpFm1 != null) && (pumpFm2 != null))
{
pumpFm1.TurnOff();
pumpFm2.TurnOff();
}
else
{
// TODO
}
}
/// <summary>
/// The currently running operation.
/// </summary>
public enum CurrentOp
{
None,
TurnOn,
TurnOff,
}
///
CurrentOp currentOp;
double powerForOp;
/// <summary>
/// Turn the pump frequency inverter on.
/// </summary>
public IOperation TurnOnOp(double powerArg)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.TurnOn;
powerForOp = powerArg;
return this;
}
/// <summary>
/// Turn the pump frequency inverter on.
/// </summary>
public IOperation TurnOffOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.TurnOff;
return this;
}
/// <summary>Start the operation</summary>
public void Start()
{
switch (currentOp)
{
case CurrentOp.TurnOn:
TurnOn(powerForOp);
return;
case CurrentOp.TurnOff:
default:
TurnOff();
return;
}
}
/// <summary>Run the operation</summary>
public Event Run()
{
return Event.TurnPumpOnOffDone;
}
/// <summary>Stop the operation</summary>
public void Stop()
{
currentOp = CurrentOp.None;
}
}
}
+46
View File
@@ -0,0 +1,46 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using System.Xml.Serialization;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.PumpTandem
{
public class PumpCfg : ComponentCfgBase, IChildComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PumpCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new PumpCfgCtrl(); }
///
/// Serialized parameters
///
public string Pump1; /// Name of the pump 1 component
public string Pump2; /// Name of the pump 2 component
/// Private parameterless constructor invoked by all other (public) constructors
PumpCfg()
{
Name = "PumpTandem";
ParentName = string.Empty;
Pump1 = string.Empty;
Pump2 = string.Empty;
}
public PumpCfg(IComponentFactory factory)
: this()
{
this.Factory = factory;
}
public string ToString(int i)
{
return string.Format("Name={0}, Pump1={1}, Pump2={2}",
Name,
string.IsNullOrEmpty(Pump1) ? "-" : Pump1,
string.IsNullOrEmpty(Pump2) ? "-" : Pump2);
}
}
}
+134
View File
@@ -0,0 +1,134 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
namespace TBF.Rig.BuiltIn.PumpTandem
{
partial class PumpCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.pump2ComboBox = new System.Windows.Forms.ComboBox();
this.pump2Label = new System.Windows.Forms.Label();
this.pump1ComboBox = new System.Windows.Forms.ComboBox();
this.pump1Label = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(140, 47);
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(30, 50);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(119, 21);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// pump2ComboBox
//
this.pump2ComboBox.Enabled = false;
this.pump2ComboBox.FormattingEnabled = true;
this.pump2ComboBox.Location = new System.Drawing.Point(140, 96);
this.pump2ComboBox.Name = "pump2ComboBox";
this.pump2ComboBox.Size = new System.Drawing.Size(130, 21);
this.pump2ComboBox.TabIndex = 12;
//
// pump2Label
//
this.pump2Label.AutoSize = true;
this.pump2Label.Location = new System.Drawing.Point(30, 99);
this.pump2Label.Name = "pump2Label";
this.pump2Label.Size = new System.Drawing.Size(43, 13);
this.pump2Label.TabIndex = 11;
this.pump2Label.Text = "Pump 2";
//
// pump1ComboBox
//
this.pump1ComboBox.Enabled = false;
this.pump1ComboBox.FormattingEnabled = true;
this.pump1ComboBox.Location = new System.Drawing.Point(140, 71);
this.pump1ComboBox.Name = "pump1ComboBox";
this.pump1ComboBox.Size = new System.Drawing.Size(130, 21);
this.pump1ComboBox.TabIndex = 10;
//
// pump1Label
//
this.pump1Label.AutoSize = true;
this.pump1Label.Location = new System.Drawing.Point(30, 74);
this.pump1Label.Name = "pump1Label";
this.pump1Label.Size = new System.Drawing.Size(43, 13);
this.pump1Label.TabIndex = 9;
this.pump1Label.Text = "Pump 1";
//
// PumpCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.pump2ComboBox);
this.Controls.Add(this.pump2Label);
this.Controls.Add(this.pump1ComboBox);
this.Controls.Add(this.pump1Label);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "PumpCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.ComboBox pump2ComboBox;
private System.Windows.Forms.Label pump2Label;
private System.Windows.Forms.ComboBox pump1ComboBox;
private System.Windows.Forms.Label pump1Label;
}
}
+108
View File
@@ -0,0 +1,108 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
using System;
using System.Windows.Forms;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
namespace TBF.Rig.BuiltIn.PumpTandem
{
public partial class PumpCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parentDlg;
public bool ShowMore { get { return false; } }
PumpCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as PumpCfg;
Redraw();
}
}
public PumpCfgCtrl()
{
InitializeComponent();
}
private void PumpCfgCtrl_Load(object sender, EventArgs e)
{
parentDlg = ParentForm as ComponentParametersDlg;
if (parentDlg == null) return;
if (parentDlg.CmpntEntities != null)
{
foreach (var cmpnt in parentDlg.CmpntEntities)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is BuiltIn.Pump.PumpFactory ||
TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.PumpWithFM.PumpFactory ||
TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Danfoss.VLT2800.PumpFactory ||
TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is BuiltIn.PumpTandem.PumpFactory)
{
pump1ComboBox.Items.Add(cmpnt.Name);
pump2ComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
pump1ComboBox.Text = string.IsNullOrEmpty(config.Pump1) ? "---" : config.Pump1;
pump2ComboBox.Text = string.IsNullOrEmpty(config.Pump2) ? "---" : config.Pump2;
}
public void Unlock()
{
nameTextBox.Enabled = true;
pump1ComboBox.Enabled = true;
pump2ComboBox.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if (!pump1ComboBox.Items.Contains(pump1ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Pump 1'";
}
if (!pump2ComboBox.Items.Contains(pump2ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Pump 2'";
}
return flags;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.Pump1 = pump1ComboBox.Text.Equals("---") ? string.Empty : pump1ComboBox.Text;
config.Pump2 = pump2ComboBox.Text.Equals("---") ? string.Empty : pump2ComboBox.Text;
return flags;
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+27
View File
@@ -0,0 +1,27 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.PumpTandem
{
public class PumpFactory : IComponentFactory
{
public string ClassName { get { return "PumpTandem"; } }
public override string ToString() { return ClassName; }
public void ResetStaticProperties() { Pump.ResetStaticProperties(); }
public IComponent DummyComponent() { return new Pump(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Pump(cfg, components); }
public IComponentCfg DefaultConfig() { return new PumpCfg(this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(PumpCfg.Serializer, component, this);
}
}
}
+325
View File
@@ -0,0 +1,325 @@
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using log4net;
using Dirichlet.Numerics;
using TBF.Rig.ControlBoard;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.BuiltIn
{
public class SetValvesOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SetValvesOp));
/// Set by the constructor
IControlBoard controlBoard;
class SwitchPoint
{
public int TimeSec; /// Relative time in [s] from the start of the operation
public IList<IValve> VOpen; /// List of valves to open in this point of time
public IList<IValve> VClose; /// List of valves to close in this point of time
public UInt128 MasksOpen; /// OR-ed bitmasks of valves to open in this point of time
public UInt128 MasksClose; /// OR-ed bitmasks of valves to close in this point of time
public SwitchPoint(int time, IList<IValve> vOpen, IList<IValve> vClose)
{
this.TimeSec = time;
this.VOpen = (vOpen == null) ? new List<IValve>() : vOpen;
this.VClose = (vClose == null) ? new List<IValve>() : vClose;
}
/// <summary>
/// Max. delay of all valves that were opened or closed
/// </summary>
/// <param name="changed">'ulong' with bits of valves that were actually changed set ot '1'</param>
/// <returns>Delay in [s]</returns>
public int MaxDelay(UInt128 changed)
{
int max = 0;
foreach (var vlv in VOpen)
{
/// Skip the delay evaluation and update in case the valve/pump have not changed
if (vlv is Valve.Valve && ((vlv as Valve.Valve).Mask & changed) == 0) continue;
if (vlv is Pump.Pump && ((vlv as Pump.Pump).Mask & changed) == 0) continue;
if (vlv is Elde.PumpWithFM.Pump && ((vlv as Elde.PumpWithFM.Pump).Mask & changed) == 0) continue;
if (vlv is Danfoss.VLT2800.Pump && ((vlv as Danfoss.VLT2800.Pump).Mask & changed) == 0) continue;
if (vlv is Modbus.PumpFM.DanfossVLT.Pump && ((vlv as Modbus.PumpFM.DanfossVLT.Pump).Mask & changed) == 0) continue;
if ((vlv != null) && (vlv.Delay > max)) max = vlv.Delay;
}
foreach (var vlv in VClose)
{
/// Skip the delay evaluation and update in case the valve/pump have not changed
if (vlv is Valve.Valve && ((vlv as Valve.Valve).Mask & changed) == 0) continue;
if (vlv is Pump.Pump && ((vlv as Pump.Pump).Mask & changed) == 0) continue;
if (vlv is Elde.PumpWithFM.Pump && ((vlv as Elde.PumpWithFM.Pump).Mask & changed) == 0) continue;
if (vlv is Danfoss.VLT2800.Pump && ((vlv as Danfoss.VLT2800.Pump).Mask & changed) == 0) continue;
if (vlv is Modbus.PumpFM.DanfossVLT.Pump && ((vlv as Modbus.PumpFM.DanfossVLT.Pump).Mask & changed) == 0) continue;
if ((vlv != null) && (vlv.Delay > max)) max = vlv.Delay;
}
return max;
}
}
IList<SwitchPoint> switchPointsRaw;
IList<SwitchPoint> switchPoints;
int nextIx;
int swStartTime;
int maxDelayTime; /// Max. delay from all valve/pump switches.
/// Relative time in [s] from the start of the operation
/// <summary>
/// Processes coupled valves and creates switch points.
/// </summary>
/// <param name="valvesOpen">A list of opening master valves</param>
/// <param name="valvesClose">A list of closing master valves</param>
/// <returns></returns>
IList<SwitchPoint> AddSwitchPoints(IList<SwitchPoint> swPoints, IList<IValve> valvesOpen, IList<IValve> valvesClose, int time)
{
int ix0 = swPoints.Count;
swPoints.Add(new SwitchPoint(time, valvesOpen, valvesClose));
foreach (var valve in StateMachine.CoupledValves)
{
if ((!valve.InvertCouple && valvesOpen.Contains(valve.CoupledTo)) ||
(valve.InvertCouple && valvesClose.Contains(valve.CoupledTo)))
{
/// The coupled valve 'valve' is opening
int lag = time + valve.LagOpening;
if (lag == time)
{
swPoints[ix0].VOpen.Add(valve);
}
else
{
swPoints.Add(new SwitchPoint(lag, ValveBase.MakeList(valve), null));
}
}
else if ((!valve.InvertCouple && valvesClose.Contains(valve.CoupledTo)) ||
(valve.InvertCouple && valvesOpen.Contains(valve.CoupledTo)))
{
/// The coupled valve 'valve' is closing
int lag = time + valve.LagClosing;
if (lag == time)
{
swPoints[ix0].VClose.Add(valve);
}
else
{
swPoints.Add(new SwitchPoint(lag, null, ValveBase.MakeList(valve)));
}
}
}
return swPoints;
}
IList<SwitchPoint> SortAndMergeSwitchPoints(IList<SwitchPoint> unsorted)
{
IList<SwitchPoint> result = new List<SwitchPoint>();
SwitchPoint lastAdded = null;
while (unsorted.Count > 0)
{
SwitchPoint first = null;
foreach (var point in unsorted)
{
if (first == null || first.TimeSec > point.TimeSec) first = point;
}
if (lastAdded == null || lastAdded.TimeSec != first.TimeSec)
{
result.Add(first);
lastAdded = first;
}
else
{
lastAdded.VOpen = ValveBase.Merge(lastAdded.VOpen, first.VOpen);
lastAdded.VClose = ValveBase.Merge(lastAdded.VClose, first.VClose);
}
unsorted.Remove(first);
}
return result;
}
void MakeMasks(IList<SwitchPoint> switchPoints, int timeShift)
{
foreach (var point in switchPoints)
{
/// Only Elde.Valve valves are used, other valves are ignored
point.MasksOpen = 0;
foreach (var valve in point.VOpen)
{
if (valve is Valve.Valve) point.MasksOpen |= (valve as Valve.Valve).Mask;
if (valve is Pump.Pump) point.MasksOpen |= (valve as Pump.Pump).Mask;
if (valve is Elde.PumpWithFM.Pump) point.MasksOpen |= (valve as Elde.PumpWithFM.Pump).Mask;
if (valve is Danfoss.VLT2800.Pump) point.MasksOpen |= (valve as Danfoss.VLT2800.Pump).Mask;
if (valve is Modbus.PumpFM.DanfossVLT.Pump) point.MasksOpen |= (valve as Modbus.PumpFM.DanfossVLT.Pump).Mask;
if (valve is PumpTandem.Pump) point.MasksOpen |= (valve as PumpTandem.Pump).Mask;
}
point.MasksClose = 0;
foreach (var valve in point.VClose)
{
if (valve is Valve.Valve) point.MasksClose |= (valve as Valve.Valve).Mask;
if (valve is Pump.Pump) point.MasksClose |= (valve as Pump.Pump).Mask;
if (valve is Elde.PumpWithFM.Pump) point.MasksClose |= (valve as Elde.PumpWithFM.Pump).Mask;
if (valve is Danfoss.VLT2800.Pump) point.MasksClose |= (valve as Danfoss.VLT2800.Pump).Mask;
if (valve is Modbus.PumpFM.DanfossVLT.Pump) point.MasksClose |= (valve as Modbus.PumpFM.DanfossVLT.Pump).Mask;
if (valve is PumpTandem.Pump) point.MasksClose |= (valve as PumpTandem.Pump).Mask;
}
point.TimeSec += timeShift;
}
}
/// <summary>
/// Open and/or close multiple valves.
/// Events: ValvesSet
/// </summary>
/// <param name="cb">Control board device</param>
/// <param name="valvesOpen">A list of opening master valves</param>
/// <param name="valvesClose">A list of closing master valves</param>
/// <remarks>Only Elde.Valve valves are used, other valves on the lists are ignored</remarks>
public SetValvesOp(IControlBoard cb, IList<IValve> valvesOpen, IList<IValve> valvesClose)
{
controlBoard = cb;
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
if (valvesOpen == null) valvesOpen = new List<IValve>();
if (valvesClose == null) valvesClose = new List<IValve>();
switchPointsRaw = new List<SwitchPoint>();
AddSwitchPoints(switchPointsRaw, valvesOpen, valvesClose, 0);
switchPoints = SortAndMergeSwitchPoints(switchPointsRaw);
int timeShift = -switchPoints[0].TimeSec;
MakeMasks(switchPoints, timeShift);
}
/// <summary>
/// Open one valve and/or close one valve.
/// Events: ValvesSet
/// </summary>
/// <param name="cb">Control board device</param>
/// <param name="valveOpen">Valve to be opened</param>
/// <param name="valveClose">Valve to be closed</param>
/// <remarks>Only Elde.Valve valves are used, other valves on the lists are ignored</remarks>
public SetValvesOp(IControlBoard cb, IValve valveOpen, IValve valveClose)
: this(cb, ValveBase.MakeList(valveOpen), ValveBase.MakeList(valveClose))
{
}
/// <summary>
/// OPEN or CLOSE start/stop valve and associated valves and/or pumps.
/// Events: ValvesSet
/// </summary>
/// <param name="controlBoard">Control board device</param>
/// <param name="open">true: open start valve, false: close start valve</param>
/// <param name="outPath">OutputPath specifying the start valve and associated valves/pumps</param>
/// <remarks>Only Elde.Valve valves are used, other valves on the lists are ignored</remarks>
public SetValvesOp(IControlBoard cb, bool open, OutputPath outPath)
{
controlBoard = cb;
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
IList<IValve> none = new List<IValve>(); /// An empty list of valves
switchPointsRaw = new List<SwitchPoint>();
if (open)
{
if (outPath.InvertSV1)
AddSwitchPoints(switchPointsRaw, none, ValveBase.MakeList(outPath.StartValve1), 0); /// close SV1
else
AddSwitchPoints(switchPointsRaw, ValveBase.MakeList(outPath.StartValve1), none, 0); /// open SV1
if (outPath.StartValve2 != null)
{
if (outPath.InvertSV2)
AddSwitchPoints(switchPointsRaw, none, ValveBase.MakeList(outPath.StartValve2), -outPath.LagSV2); /// close SV2 after lag
else
AddSwitchPoints(switchPointsRaw, ValveBase.MakeList(outPath.StartValve2), none, -outPath.LagSV2); /// open SV2 after lag
}
if (outPath.StartValve3 != null)
{
if (outPath.InvertSV3)
AddSwitchPoints(switchPointsRaw, none, ValveBase.MakeList(outPath.StartValve3), -outPath.LagSV3); /// close SV3 after lag
else
AddSwitchPoints(switchPointsRaw, ValveBase.MakeList(outPath.StartValve3), none, -outPath.LagSV3); /// open SV3 after lag
}
}
else
{
if (outPath.InvertSV1)
AddSwitchPoints(switchPointsRaw, ValveBase.MakeList(outPath.StartValve1), none, 0); /// open SV1
else
AddSwitchPoints(switchPointsRaw, none, ValveBase.MakeList(outPath.StartValve1), 0); /// close SV1
if (outPath.StartValve2 != null)
{
if (outPath.InvertSV2)
AddSwitchPoints(switchPointsRaw, ValveBase.MakeList(outPath.StartValve2), none, outPath.LagSV2); /// open SV2 after lag
else
AddSwitchPoints(switchPointsRaw, none, ValveBase.MakeList(outPath.StartValve2), outPath.LagSV2); /// close SV2 after lag
}
if (outPath.StartValve3 != null)
{
if (outPath.InvertSV3)
AddSwitchPoints(switchPointsRaw, ValveBase.MakeList(outPath.StartValve3), none, outPath.LagSV3); /// open SV3 after lag
else
AddSwitchPoints(switchPointsRaw, none, ValveBase.MakeList(outPath.StartValve3), outPath.LagSV3); /// close SV3 after lag
}
}
switchPoints = SortAndMergeSwitchPoints(switchPointsRaw);
int timeShift = -switchPoints[0].TimeSec;
MakeMasks(switchPoints, timeShift);
}
/// <summary>Start this operation</summary>
public void Start()
{
UInt128 changed = controlBoard.SetValves(switchPoints[0].MasksOpen, switchPoints[0].MasksClose, StateMachine.ExtendedValves);
swStartTime = StateMachine.Time;
maxDelayTime = switchPoints[0].MaxDelay(changed);
nextIx = 1;
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.SetValvesDone
/// </returns>
public Event Run()
{
if (nextIx >= switchPoints.Count)
{
return (StateMachine.Time >= swStartTime + maxDelayTime) ? Event.ValvesSet : Event.ValvesBusy;
}
if (StateMachine.Time >= swStartTime + switchPoints[nextIx].TimeSec)
{
UInt128 changed = controlBoard.SetValves(switchPoints[nextIx].MasksOpen, switchPoints[nextIx].MasksClose, StateMachine.ExtendedValves);
int nextDelay = switchPoints[nextIx].MaxDelay(changed);
if (switchPoints[nextIx].TimeSec + nextDelay > maxDelayTime)
{
maxDelayTime = switchPoints[nextIx].TimeSec + nextDelay;
}
nextIx++;
}
return Event.ValvesBusy;
}
/// <summary>Start this operation</summary>
public void Stop()
{
}
}
}
+103
View File
@@ -0,0 +1,103 @@
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using Dirichlet.Numerics;
using log4net;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.BuiltIn.Valve
{
/// <summary>
/// Plain valve, open/close state is controlled by 1 bit from the route
/// </summary>
public class Valve : ValveBase, IValve, SchematicDrawing.IDrawingItCmpnt
{
private static readonly ILog log = LogManager.GetLogger(typeof(Valve));
public override string ToString() { return string.Format("Valve({0})", Cfg.ToString(1)); }
readonly ValveCfg valveCfg;
public SchematicDrawing.IDrawingItem DrawingItem { get { return valveCfg as SchematicDrawing.IDrawingItem; } }
readonly TBF.Rig.ControlBoard.IControlBoard controlBoard;
public ValveCategory Category { get { return valveCfg.Category; } }
public int Delay { get { return valveCfg.OpenCloseTime; } }
public bool Inverted { get { return valveCfg.Inverted; } }
public IValve CoupledTo { get { return coupledTo; } }
readonly IValve coupledTo;
public bool InvertCouple { get { return valveCfg.InvertCouple; } }
public int LagOpening { get { return valveCfg.LagOpening; } }
public int LagClosing { get { return valveCfg.LagClosing; } }
public readonly UInt128 Mask; /// derived from bitPosition in the constructor
public int BitPosition { get { return valveCfg.BitNr; } }
public Valve()
{
}
public Valve(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
valveCfg = cfg as ValveCfg;
controlBoard = TbfComponents.FindComponent(cfg.ParentName, components) as TBF.Rig.ControlBoard.IControlBoard;
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
if (valveCfg.BitNr < 0 || valveCfg.BitNr >= 128)
{
throw new ArgumentOutOfRangeException("position");
}
this.Mask = (((UInt128)1) << valveCfg.BitNr);
if (valveCfg.CoupledToName != null)
{
coupledTo = (IValve)TbfComponents.FindComponent(valveCfg.CoupledToName, components);
}
log.Warn(this.ToString());
}
public bool State
{
get { return (controlBoard.Route & Mask) != 0; }
}
#region Configuration Change Handling
public static void OnCfgChange(object sender, CfgChangeArgs args)
{
if (CfgChangeHandler == null) return;
try { CfgChangeHandler(sender, args); }
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
}
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
public override void StartChangeHandler()
{
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
{
ValveCfg tmpcfg = args.Cfg as ValveCfg;
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
{
if (args.Command == CfgChangeCmd.CfgChange)
{
valveCfg.OpenCloseTime = tmpcfg.OpenCloseTime;
valveCfg.LagOpening = tmpcfg.LagOpening;
valveCfg.LagClosing = tmpcfg.LagClosing;
}
}
};
}
#endregion Configuration Change Handling
}
}
+94
View File
@@ -0,0 +1,94 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using System.Xml.Serialization;
using SchematicDrawing;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.Valve
{
public class ValveCfg : ComponentCfgBase, IChildComponentCfg, IRouteBasedDrawingItem
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ValveCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new ValveCfgCtrl(); }
///
/// Serialized parameters
///
public int BitNr { get; set; } /// Bit-position
public bool Inverted { get; set; } /// When true the valve function is inverted: 0 = open, 1 = closed
public ValveCategory Category; /// None, Feeding, Bench or Output
public int OpenCloseTime; /// Delay for SetValvesOp operations
///
public string CoupledToName; /// Name of the coupled valve or null
public bool InvertCouple; /// The coupled valve has inverted position
public int LagOpening; /// Delay (referred to the master valve) when opening this valve in [s]
public int LagClosing; /// Delay (referred to the master valve) when closing this valve in [s]
/// Negative values of delays mean an earlier function of the coupled valve.
/// 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; }
[XmlIgnore]
public IList<GNode> GNodes { get; set; }
[XmlIgnore]
public IList<GEdge> EdgesToSet { get; set; }
/// Private parameterless constructor invoked by all other (public) constructors
ValveCfg()
{
GNodes = new List<GNode>();
EdgesToSet = new List<GEdge>();
}
public ValveCfg(IComponentFactory factory)
: this()
{
Shape = Shape.Valve;
Sz = Sz.M;
Factory = factory;
Name = "V";
ParentName = "UniCB";
BitNr = 0;
Category = ValveCategory.None;
OpenCloseTime = 1;
Inverted = false;
CoupledToName = string.Empty;
InvertCouple = false;
LagOpening = 0;
LagClosing = 0;
}
public string ToString(int i)
{
return string.Format("{0}({1}) {2}[{3},{4}] bit={5} inv={6} delay={7}s cat={8} coupled to={9} inv.couple={10} lagO={11}s lagC={12}s",
Name,
string.IsNullOrEmpty(ParentName) ? "-" : ParentName,
Shape,
X,
Y,
BitNr,
Inverted ? "yes" : "no",
OpenCloseTime,
Category,
string.IsNullOrEmpty(CoupledToName) ? "-" : CoupledToName,
InvertCouple ? "yes" : "no",
LagOpening,
LagClosing);
}
}
}
+293
View File
@@ -0,0 +1,293 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
namespace TBF.Rig.BuiltIn.Valve
{
partial class ValveCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.bitPositionTextBox = new System.Windows.Forms.TextBox();
this.bitPositionLabel = 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.classNameLabel = new System.Windows.Forms.Label();
this.coupledToLabel = new System.Windows.Forms.Label();
this.invertCoupleCheckBox = new System.Windows.Forms.CheckBox();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.lagOpeningLabel = new System.Windows.Forms.Label();
this.lagClosingLabel = new System.Windows.Forms.Label();
this.lagOpeningTextBox = new System.Windows.Forms.TextBox();
this.lagClosingTextBox = new System.Windows.Forms.TextBox();
this.coupledToComboBox = new System.Windows.Forms.ComboBox();
this.categoryLabel = new System.Windows.Forms.Label();
this.categoryComboBox = new System.Windows.Forms.ComboBox();
this.openCloseTimeTextBox = new System.Windows.Forms.TextBox();
this.openCloseTimeLabel = new System.Windows.Forms.Label();
this.invertedCheckBox = new System.Windows.Forms.CheckBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// bitPositionTextBox
//
this.bitPositionTextBox.Enabled = false;
this.bitPositionTextBox.Location = new System.Drawing.Point(158, 99);
this.bitPositionTextBox.Name = "bitPositionTextBox";
this.bitPositionTextBox.Size = new System.Drawing.Size(81, 20);
this.bitPositionTextBox.TabIndex = 8;
//
// bitPositionLabel
//
this.bitPositionLabel.AutoSize = true;
this.bitPositionLabel.Location = new System.Drawing.Point(42, 102);
this.bitPositionLabel.Name = "bitPositionLabel";
this.bitPositionLabel.Size = new System.Drawing.Size(58, 13);
this.bitPositionLabel.TabIndex = 7;
this.bitPositionLabel.Text = "Bit position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(42, 54);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(67, 13);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(158, 28);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(132, 20);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(42, 31);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(156, 8);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// coupledToLabel
//
this.coupledToLabel.AutoSize = true;
this.coupledToLabel.Location = new System.Drawing.Point(42, 125);
this.coupledToLabel.Name = "coupledToLabel";
this.coupledToLabel.Size = new System.Drawing.Size(52, 13);
this.coupledToLabel.TabIndex = 10;
this.coupledToLabel.Text = "Copled to";
//
// invertCoupleCheckBox
//
this.invertCoupleCheckBox.AutoSize = true;
this.invertCoupleCheckBox.Enabled = false;
this.invertCoupleCheckBox.Location = new System.Drawing.Point(248, 124);
this.invertCoupleCheckBox.Name = "invertCoupleCheckBox";
this.invertCoupleCheckBox.Size = new System.Drawing.Size(53, 17);
this.invertCoupleCheckBox.TabIndex = 12;
this.invertCoupleCheckBox.Text = "Invert";
this.invertCoupleCheckBox.UseVisualStyleBackColor = true;
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(158, 51);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(132, 21);
this.parentNameComboBox.TabIndex = 4;
//
// lagOpeningLabel
//
this.lagOpeningLabel.AutoSize = true;
this.lagOpeningLabel.Location = new System.Drawing.Point(16, 47);
this.lagOpeningLabel.Name = "lagOpeningLabel";
this.lagOpeningLabel.Size = new System.Drawing.Size(162, 13);
this.lagOpeningLabel.TabIndex = 15;
this.lagOpeningLabel.Text = "Lag when opening coupled v. [s]";
//
// lagClosingLabel
//
this.lagClosingLabel.AutoSize = true;
this.lagClosingLabel.Location = new System.Drawing.Point(16, 70);
this.lagClosingLabel.Name = "lagClosingLabel";
this.lagClosingLabel.Size = new System.Drawing.Size(157, 13);
this.lagClosingLabel.TabIndex = 17;
this.lagClosingLabel.Text = "Lag when closing coupled v. [s]";
//
// lagOpeningTextBox
//
this.lagOpeningTextBox.Enabled = false;
this.lagOpeningTextBox.Location = new System.Drawing.Point(184, 44);
this.lagOpeningTextBox.Name = "lagOpeningTextBox";
this.lagOpeningTextBox.Size = new System.Drawing.Size(81, 20);
this.lagOpeningTextBox.TabIndex = 16;
//
// lagClosingTextBox
//
this.lagClosingTextBox.Enabled = false;
this.lagClosingTextBox.Location = new System.Drawing.Point(184, 67);
this.lagClosingTextBox.Name = "lagClosingTextBox";
this.lagClosingTextBox.Size = new System.Drawing.Size(81, 20);
this.lagClosingTextBox.TabIndex = 18;
//
// coupledToComboBox
//
this.coupledToComboBox.Enabled = false;
this.coupledToComboBox.FormattingEnabled = true;
this.coupledToComboBox.Location = new System.Drawing.Point(158, 122);
this.coupledToComboBox.Name = "coupledToComboBox";
this.coupledToComboBox.Size = new System.Drawing.Size(81, 21);
this.coupledToComboBox.TabIndex = 11;
//
// categoryLabel
//
this.categoryLabel.AutoSize = true;
this.categoryLabel.Location = new System.Drawing.Point(42, 78);
this.categoryLabel.Name = "categoryLabel";
this.categoryLabel.Size = new System.Drawing.Size(49, 13);
this.categoryLabel.TabIndex = 5;
this.categoryLabel.Text = "Category";
//
// categoryComboBox
//
this.categoryComboBox.Enabled = false;
this.categoryComboBox.FormattingEnabled = true;
this.categoryComboBox.Location = new System.Drawing.Point(158, 75);
this.categoryComboBox.Name = "categoryComboBox";
this.categoryComboBox.Size = new System.Drawing.Size(132, 21);
this.categoryComboBox.TabIndex = 6;
//
// openCloseTimeTextBox
//
this.openCloseTimeTextBox.Enabled = false;
this.openCloseTimeTextBox.Location = new System.Drawing.Point(184, 21);
this.openCloseTimeTextBox.Name = "openCloseTimeTextBox";
this.openCloseTimeTextBox.Size = new System.Drawing.Size(81, 20);
this.openCloseTimeTextBox.TabIndex = 14;
//
// openCloseTimeLabel
//
this.openCloseTimeLabel.AutoSize = true;
this.openCloseTimeLabel.Location = new System.Drawing.Point(16, 24);
this.openCloseTimeLabel.Name = "openCloseTimeLabel";
this.openCloseTimeLabel.Size = new System.Drawing.Size(99, 13);
this.openCloseTimeLabel.TabIndex = 13;
this.openCloseTimeLabel.Text = "Open/close time [s]";
//
// invertedCheckBox
//
this.invertedCheckBox.AutoSize = true;
this.invertedCheckBox.Enabled = false;
this.invertedCheckBox.Location = new System.Drawing.Point(248, 101);
this.invertedCheckBox.Name = "invertedCheckBox";
this.invertedCheckBox.Size = new System.Drawing.Size(65, 17);
this.invertedCheckBox.TabIndex = 9;
this.invertedCheckBox.Text = "Inverted";
this.invertedCheckBox.UseVisualStyleBackColor = true;
//
// groupBox1
//
this.groupBox1.Controls.Add(this.openCloseTimeLabel);
this.groupBox1.Controls.Add(this.lagOpeningLabel);
this.groupBox1.Controls.Add(this.openCloseTimeTextBox);
this.groupBox1.Controls.Add(this.lagClosingLabel);
this.groupBox1.Controls.Add(this.lagOpeningTextBox);
this.groupBox1.Controls.Add(this.lagClosingTextBox);
this.groupBox1.Location = new System.Drawing.Point(25, 161);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(301, 97);
this.groupBox1.TabIndex = 19;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Parameters applied immediately (no restart required)";
//
// ValveCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.invertedCheckBox);
this.Controls.Add(this.categoryComboBox);
this.Controls.Add(this.categoryLabel);
this.Controls.Add(this.coupledToComboBox);
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.invertCoupleCheckBox);
this.Controls.Add(this.coupledToLabel);
this.Controls.Add(this.bitPositionTextBox);
this.Controls.Add(this.bitPositionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "ValveCfgCtrl";
this.Size = new System.Drawing.Size(388, 291);
this.Load += new System.EventHandler(this.ValveCfgCtrl_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox bitPositionTextBox;
private System.Windows.Forms.Label bitPositionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.Label coupledToLabel;
private System.Windows.Forms.CheckBox invertCoupleCheckBox;
private System.Windows.Forms.ComboBox parentNameComboBox;
private System.Windows.Forms.Label lagOpeningLabel;
private System.Windows.Forms.Label lagClosingLabel;
private System.Windows.Forms.TextBox lagOpeningTextBox;
private System.Windows.Forms.TextBox lagClosingTextBox;
private System.Windows.Forms.ComboBox coupledToComboBox;
private System.Windows.Forms.Label categoryLabel;
private System.Windows.Forms.ComboBox categoryComboBox;
private System.Windows.Forms.TextBox openCloseTimeTextBox;
private System.Windows.Forms.Label openCloseTimeLabel;
private System.Windows.Forms.CheckBox invertedCheckBox;
private System.Windows.Forms.GroupBox groupBox1;
}
}
+203
View File
@@ -0,0 +1,203 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System;
using System.Windows.Forms;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
using TBF.UI.Bench.Components;
namespace TBF.Rig.BuiltIn.Valve
{
public partial class ValveCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
public bool ShowMore { get { return false; } }
ValveCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as ValveCfg;
Redraw();
}
}
public ValveCfgCtrl()
{
InitializeComponent();
}
private void ValveCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
categoryComboBox.Items.Add(ValveCategory.Feeding.ToString());
categoryComboBox.Items.Add(ValveCategory.Bench.ToString());
categoryComboBox.Items.Add(ValveCategory.Output.ToString());
categoryComboBox.Items.Add(ValveCategory.None.ToString());
if (parent.CmpntEntities != null)
{
parentNameComboBox.Items.Add("---");
coupledToComboBox.Items.Add("---");
foreach (var cmpnt in parent.CmpntEntities)
{
if (cmpnt.ClassName.Contains("ControlBoard"))
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is BuiltIn.Valve.ValveFactory)
{
coupledToComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
bitPositionTextBox.Text = config.BitNr.ToString();
invertedCheckBox.Checked = config.Inverted;
openCloseTimeTextBox.Text = config.OpenCloseTime.ToString();
categoryComboBox.Text = config.Category.ToString();
coupledToComboBox.Text = string.IsNullOrEmpty(config.CoupledToName) ? "---" : config.CoupledToName;
invertCoupleCheckBox.Checked = config.InvertCouple;
lagOpeningTextBox.Text = config.LagOpening.ToString();
lagClosingTextBox.Text = config.LagClosing.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
bitPositionTextBox.Enabled = true;
invertedCheckBox.Enabled = true;
openCloseTimeTextBox.Enabled = true;
categoryComboBox.Enabled = true;
coupledToComboBox.Enabled = true;
invertCoupleCheckBox.Enabled = true;
lagOpeningTextBox.Enabled = true;
lagClosingTextBox.Enabled = true;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
string newParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
int newBitPosition = int.Parse(bitPositionTextBox.Text);
string newCoupledToName = coupledToComboBox.Text.Equals("---") ? string.Empty : coupledToComboBox.Text;
int newLagOpening = int.Parse(lagOpeningTextBox.Text);
int newLagClosing = int.Parse(lagClosingTextBox.Text);
int newOpenCloseTime = int.Parse(openCloseTimeTextBox.Text);
ValveCategory newCategory;
if (categoryComboBox.Text.Equals(ValveCategory.Feeding.ToString())) newCategory = ValveCategory.Feeding;
else if (categoryComboBox.Text.Equals(ValveCategory.Bench.ToString())) newCategory = ValveCategory.Bench;
else if (categoryComboBox.Text.Equals(ValveCategory.Output.ToString())) newCategory = ValveCategory.Output;
else newCategory = ValveCategory.None;
if (config.Name != nameTextBox.Text ||
config.ParentName != newParentName ||
config.BitNr != newBitPosition ||
config.Category != newCategory ||
config.Inverted != invertedCheckBox.Checked ||
config.CoupledToName != newCoupledToName ||
config.InvertCouple != invertCoupleCheckBox.Checked)
{
config.Name = nameTextBox.Text;
config.ParentName = newParentName;
config.BitNr = newBitPosition;
config.Category = newCategory;
config.Inverted = invertedCheckBox.Checked;
config.CoupledToName = newCoupledToName;
config.InvertCouple = invertCoupleCheckBox.Checked;
flags |= (CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
}
if (config.OpenCloseTime != newOpenCloseTime ||
config.LagOpening != newLagOpening ||
config.LagClosing != newLagClosing)
{
config.OpenCloseTime = newOpenCloseTime;
config.LagOpening = newLagOpening;
config.LagClosing = newLagClosing;
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
}
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
{
Valve.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
}
return flags;
}
public CfgUpdateFlags 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 (!categoryComboBox.Items.Contains(categoryComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Category'";
}
if (!coupledToComboBox.Items.Contains(coupledToComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Coupled To'";
}
if (!int.TryParse(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 128)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 127";
}
if (!int.TryParse(openCloseTimeTextBox.Text, out dummy) || dummy < 0 || dummy > 300 || (dummy % StateMachine.Period) != 0)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Open/close time' should be between 0 and 300 s";
if (dummy % StateMachine.Period != 0)
message += Environment.NewLine + string.Format("and a multiple of {0}", StateMachine.Period);
}
if (!int.TryParse(lagOpeningTextBox.Text, out dummy) || (dummy % StateMachine.Period) != 0)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format("'Delay when opening' error should be a multiple of {0}", StateMachine.Period);
}
if (!int.TryParse(lagClosingTextBox.Text, out dummy) || (dummy % StateMachine.Period) != 0)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format("'Delay when closing' error should be a multiple of {0}", StateMachine.Period);
}
return flags;
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+27
View File
@@ -0,0 +1,27 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.Valve
{
public class ValveFactory : IComponentFactory
{
public string ClassName { get { return "Valve"; } }
public override string ToString() { return ClassName; }
public void ResetStaticProperties() { Valve.ResetStaticProperties(); }
public IComponent DummyComponent() { return new Valve(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Valve(cfg, components); }
public IComponentCfg DefaultConfig() { return new ValveCfg(this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(ValveCfg.Serializer, component, this);
}
}
}
+103
View File
@@ -0,0 +1,103 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.BuiltIn
{
public class ValveBase : ComponentBase
{
public ValveBase()
{
}
/// <summary>
/// Invokes ComponentBase constructor
/// </summary>
public ValveBase(Generic.IComponentCfg cfg) : base(cfg)
{
}
/// <summary>
/// Process the list of components and return all valves (masters and coupled)
/// </summary>
public static IList<IValve> AllValves(IList<Generic.IComponent> cmpnts)
{
IList<IValve> result = new List<IValve>();
foreach (var cmpnt in cmpnts) if (cmpnt is IValve) result.Add(cmpnt as IValve);
return result;
}
/// <summary>
/// Process the list of components and return masters valves
/// </summary>
public static IList<IValve> GetMasterValves(IList<Generic.IComponent> cmpnts)
{
IList<IValve> result = new List<IValve>();
foreach (var cmpnt in cmpnts)
{
IValve valve = cmpnt as IValve;
if (valve != null && valve.CoupledTo == null) result.Add(valve);
}
return result;
}
/// <summary>
/// Process the list of components and return coupled valves
/// </summary>
public static IList<IValve> CoupledValves(IList<Generic.IComponent> cmpnts)
{
IList<IValve> result = new List<IValve>();
foreach (var cmpnt in cmpnts)
{
IValve valve = cmpnt as IValve;
if (valve != null && valve.CoupledTo != null) result.Add(valve);
}
return result;
}
/// <summary>
/// Process the list of components and return extended valves
/// </summary>
public static IList<BuiltIn.ValveEx.Valve> ExtendedValves(IList<Generic.IComponent> cmpnts)
{
IList<BuiltIn.ValveEx.Valve> result = new List<BuiltIn.ValveEx.Valve>();
foreach (var cmpnt in cmpnts)
{
if (cmpnt is BuiltIn.ValveEx.Valve) result.Add(cmpnt as BuiltIn.ValveEx.Valve);
}
return result;
}
/// <summary>
/// Create a list with one valved passed as an argument to this function
/// </summary>
/// <param name="valve">Valve</param>
/// <returns>List with one valve</returns>
public static IList<IValve> MakeList(IValve valve)
{
IList<IValve> result = new List<IValve>();
if (valve != null) result.Add(valve);
return result;
}
public static IList<IValve> Merge(IList<IValve> valves1, IList<IValve> valves2)
{
IList<IValve> result = new List<IValve>();
if (valves1 != null) foreach (var valve in valves1) result.Add(valve);
if (valves2 != null) foreach (var valve in valves2) result.Add(valve);
return result;
}
public static IList<IValve> Merge(IList<IValve> valves1, IList<IValve> valves2, IList<IValve> valves3)
{
IList<IValve> result = new List<IValve>();
if (valves1 != null) foreach (var valve in valves1) result.Add(valve);
if (valves2 != null) foreach (var valve in valves2) result.Add(valve);
if (valves3 != null) foreach (var valve in valves3) result.Add(valve);
return result;
}
}
}
+93
View File
@@ -0,0 +1,93 @@
///
/// Copyright (c) 2015-2016 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using log4net;
using TBF.Rig.GenericDevices;
using Dirichlet.Numerics;
namespace TBF.Rig.BuiltIn.ValveEx
{
public class Valve : ComponentBase, Generic.IComponent
{
private static readonly ILog log = LogManager.GetLogger(typeof(Valve));
public override string ToString() { return string.Format("ValveEx({0})", Cfg.ToString(1)); }
readonly ValveCfg valveCfg;
public readonly UInt128 Mask; /// derived from bitPosition in the constructor
///
public readonly IValve[] InputValves;
public Valve()
{
}
public Valve(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
valveCfg = cfg as ValveCfg;
//controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
//if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
if (valveCfg.BitPosition < 0 || valveCfg.BitPosition >= 128)
{
throw new ArgumentOutOfRangeException("position");
}
this.Mask = (((UInt128)1) << valveCfg.BitPosition);
InputValves = new IValve[valveCfg.InputValvesCount];
InputValves[0] = TbfComponents.FindComponent(valveCfg.Input1, components) as IValve;
InputValves[1] = TbfComponents.FindComponent(valveCfg.Input2, components) as IValve;
if (InputValves.Length > 2)
{
InputValves[2] = TbfComponents.FindComponent(valveCfg.Input3, components) as IValve;
}
if (InputValves.Length > 3)
{
InputValves[3] = TbfComponents.FindComponent(valveCfg.Input4, components) as IValve;
}
if (InputValves.Length > 4)
{
InputValves[4] = TbfComponents.FindComponent(valveCfg.Input5, components) as IValve;
}
log.Warn(this.ToString());
}
public void UpdateRoute(ref UInt128 route)
{
bool output;
if (valveCfg.LogicalOp == ValveExOperation.And)
{
output = true;
foreach (var valve in InputValves)
{
if (valve != null) output = output && valve.State;
}
}
else if (valveCfg.LogicalOp == ValveExOperation.Or)
{
output = false;
foreach (var valve in InputValves)
{
if (valve != null) output = output || valve.State;
}
}
else
return;
if (output != valveCfg.InvertOutput)
{
route = route | Mask; /// Set the output bit to true
}
else
{
route = route & (~Mask); /// Reset the output bit to false
}
}
}
}
+68
View File
@@ -0,0 +1,68 @@
///
/// Copyright (c) 2015-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using System.Xml.Serialization;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.ValveEx
{
public class ValveCfg : ComponentCfgBase, IComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ValveCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new ValveCfgCtrl(); }
///
/// Serialized parameters
///
public int BitPosition; /// Bit-position
///
public ValveExOperation LogicalOp; /// Logical operation between input valves
public bool InvertOutput; /// Invert the output of logical operation
public int InputValvesCount;
public string Input1; /// Input valve 1
public string Input2; /// Input valve 2
public string Input3; /// Input valve 3
public string Input4; /// Input valve 4
public string Input5; /// Input valve 5
/// Private parameterless constructor invoked by all other (public) constructors
ValveCfg()
{
Name = "VEx";
ParentName = string.Empty;
BitPosition = 0;
LogicalOp = ValveExOperation.And;
InvertOutput = false;
InputValvesCount = 2;
Input1 = string.Empty;
Input2 = string.Empty;
Input3 = string.Empty;
Input4 = string.Empty;
Input5 = string.Empty;
}
public ValveCfg(IComponentFactory factory)
: this()
{
this.Factory = factory;
}
public string ToString(int i)
{
return string.Format("Name={0}, Bit={1}, LogOp.={2}, Inv.Output={3}, #inputs={4}, I1={5}, I2={6}, I3={7}, I4={8}s, I5={9}",
Name,
BitPosition,
(LogicalOp == ValveExOperation.And) ? "AND" : "OR",
InvertOutput ? "yes" : "no",
InputValvesCount,
Input1,
Input2,
Input3,
Input4,
Input5);
}
}
}
+291
View File
@@ -0,0 +1,291 @@
///
/// Copyright (c) 2015 Sensus Metering Systems
///
namespace TBF.Rig.BuiltIn.ValveEx
{
partial class ValveCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.bitPositionTextBox = new System.Windows.Forms.TextBox();
this.bitPositionLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.inputsCountLabel = new System.Windows.Forms.Label();
this.inputsCountTextBox = new System.Windows.Forms.TextBox();
this.logicalOpLabel = new System.Windows.Forms.Label();
this.logicalOpComboBox = new System.Windows.Forms.ComboBox();
this.invertedOutpCheckBox = new System.Windows.Forms.CheckBox();
this.input1ComboBox = new System.Windows.Forms.ComboBox();
this.input1Label = new System.Windows.Forms.Label();
this.input2ComboBox = new System.Windows.Forms.ComboBox();
this.input2Label = new System.Windows.Forms.Label();
this.input3ComboBox = new System.Windows.Forms.ComboBox();
this.input3Label = new System.Windows.Forms.Label();
this.input4ComboBox = new System.Windows.Forms.ComboBox();
this.input4Label = new System.Windows.Forms.Label();
this.input5ComboBox = new System.Windows.Forms.ComboBox();
this.input5Label = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// bitPositionTextBox
//
this.bitPositionTextBox.Enabled = false;
this.bitPositionTextBox.Location = new System.Drawing.Point(117, 58);
this.bitPositionTextBox.Name = "bitPositionTextBox";
this.bitPositionTextBox.Size = new System.Drawing.Size(66, 20);
this.bitPositionTextBox.TabIndex = 4;
//
// bitPositionLabel
//
this.bitPositionLabel.AutoSize = true;
this.bitPositionLabel.Location = new System.Drawing.Point(17, 61);
this.bitPositionLabel.Name = "bitPositionLabel";
this.bitPositionLabel.Size = new System.Drawing.Size(58, 13);
this.bitPositionLabel.TabIndex = 3;
this.bitPositionLabel.Text = "Bit position";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(117, 35);
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(17, 38);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(115, 15);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// inputsCountLabel
//
this.inputsCountLabel.AutoSize = true;
this.inputsCountLabel.Location = new System.Drawing.Point(17, 108);
this.inputsCountLabel.Name = "inputsCountLabel";
this.inputsCountLabel.Size = new System.Drawing.Size(66, 13);
this.inputsCountLabel.TabIndex = 8;
this.inputsCountLabel.Text = "Inputs count";
//
// inputsCountTextBox
//
this.inputsCountTextBox.Enabled = false;
this.inputsCountTextBox.Location = new System.Drawing.Point(117, 105);
this.inputsCountTextBox.Name = "inputsCountTextBox";
this.inputsCountTextBox.Size = new System.Drawing.Size(66, 20);
this.inputsCountTextBox.TabIndex = 9;
this.inputsCountTextBox.TextChanged += new System.EventHandler(this.inputsCountTextBox_TextChanged);
//
// logicalOpLabel
//
this.logicalOpLabel.AutoSize = true;
this.logicalOpLabel.Location = new System.Drawing.Point(17, 84);
this.logicalOpLabel.Name = "logicalOpLabel";
this.logicalOpLabel.Size = new System.Drawing.Size(88, 13);
this.logicalOpLabel.TabIndex = 6;
this.logicalOpLabel.Text = "Logical operation";
//
// logicalOpComboBox
//
this.logicalOpComboBox.Enabled = false;
this.logicalOpComboBox.FormattingEnabled = true;
this.logicalOpComboBox.Location = new System.Drawing.Point(117, 81);
this.logicalOpComboBox.Name = "logicalOpComboBox";
this.logicalOpComboBox.Size = new System.Drawing.Size(66, 21);
this.logicalOpComboBox.TabIndex = 7;
//
// invertedOutpCheckBox
//
this.invertedOutpCheckBox.AutoSize = true;
this.invertedOutpCheckBox.Enabled = false;
this.invertedOutpCheckBox.Location = new System.Drawing.Point(196, 61);
this.invertedOutpCheckBox.Name = "invertedOutpCheckBox";
this.invertedOutpCheckBox.Size = new System.Drawing.Size(98, 17);
this.invertedOutpCheckBox.TabIndex = 5;
this.invertedOutpCheckBox.Text = "Inverted output";
this.invertedOutpCheckBox.UseVisualStyleBackColor = true;
//
// input1ComboBox
//
this.input1ComboBox.Enabled = false;
this.input1ComboBox.FormattingEnabled = true;
this.input1ComboBox.Location = new System.Drawing.Point(117, 127);
this.input1ComboBox.Name = "input1ComboBox";
this.input1ComboBox.Size = new System.Drawing.Size(130, 21);
this.input1ComboBox.TabIndex = 11;
//
// input1Label
//
this.input1Label.AutoSize = true;
this.input1Label.Location = new System.Drawing.Point(18, 130);
this.input1Label.Name = "input1Label";
this.input1Label.Size = new System.Drawing.Size(40, 13);
this.input1Label.TabIndex = 10;
this.input1Label.Text = "Input 1";
//
// input2ComboBox
//
this.input2ComboBox.Enabled = false;
this.input2ComboBox.FormattingEnabled = true;
this.input2ComboBox.Location = new System.Drawing.Point(117, 150);
this.input2ComboBox.Name = "input2ComboBox";
this.input2ComboBox.Size = new System.Drawing.Size(130, 21);
this.input2ComboBox.TabIndex = 13;
//
// input2Label
//
this.input2Label.AutoSize = true;
this.input2Label.Location = new System.Drawing.Point(17, 153);
this.input2Label.Name = "input2Label";
this.input2Label.Size = new System.Drawing.Size(40, 13);
this.input2Label.TabIndex = 12;
this.input2Label.Text = "Input 2";
//
// input3ComboBox
//
this.input3ComboBox.Enabled = false;
this.input3ComboBox.FormattingEnabled = true;
this.input3ComboBox.Location = new System.Drawing.Point(117, 173);
this.input3ComboBox.Name = "input3ComboBox";
this.input3ComboBox.Size = new System.Drawing.Size(130, 21);
this.input3ComboBox.TabIndex = 15;
//
// input3Label
//
this.input3Label.AutoSize = true;
this.input3Label.Location = new System.Drawing.Point(18, 176);
this.input3Label.Name = "input3Label";
this.input3Label.Size = new System.Drawing.Size(40, 13);
this.input3Label.TabIndex = 14;
this.input3Label.Text = "Input 3";
//
// input4ComboBox
//
this.input4ComboBox.Enabled = false;
this.input4ComboBox.FormattingEnabled = true;
this.input4ComboBox.Location = new System.Drawing.Point(117, 196);
this.input4ComboBox.Name = "input4ComboBox";
this.input4ComboBox.Size = new System.Drawing.Size(130, 21);
this.input4ComboBox.TabIndex = 17;
//
// input4Label
//
this.input4Label.AutoSize = true;
this.input4Label.Location = new System.Drawing.Point(18, 199);
this.input4Label.Name = "input4Label";
this.input4Label.Size = new System.Drawing.Size(40, 13);
this.input4Label.TabIndex = 16;
this.input4Label.Text = "Input 4";
//
// input5ComboBox
//
this.input5ComboBox.Enabled = false;
this.input5ComboBox.FormattingEnabled = true;
this.input5ComboBox.Location = new System.Drawing.Point(117, 219);
this.input5ComboBox.Name = "input5ComboBox";
this.input5ComboBox.Size = new System.Drawing.Size(130, 21);
this.input5ComboBox.TabIndex = 19;
//
// input5Label
//
this.input5Label.AutoSize = true;
this.input5Label.Location = new System.Drawing.Point(18, 222);
this.input5Label.Name = "input5Label";
this.input5Label.Size = new System.Drawing.Size(40, 13);
this.input5Label.TabIndex = 18;
this.input5Label.Text = "Input 5";
//
// ValveCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.input5ComboBox);
this.Controls.Add(this.input5Label);
this.Controls.Add(this.input4ComboBox);
this.Controls.Add(this.input4Label);
this.Controls.Add(this.input3ComboBox);
this.Controls.Add(this.input3Label);
this.Controls.Add(this.input2ComboBox);
this.Controls.Add(this.input2Label);
this.Controls.Add(this.input1ComboBox);
this.Controls.Add(this.input1Label);
this.Controls.Add(this.invertedOutpCheckBox);
this.Controls.Add(this.logicalOpComboBox);
this.Controls.Add(this.logicalOpLabel);
this.Controls.Add(this.inputsCountTextBox);
this.Controls.Add(this.inputsCountLabel);
this.Controls.Add(this.bitPositionTextBox);
this.Controls.Add(this.bitPositionLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "ValveCfgCtrl";
this.Size = new System.Drawing.Size(300, 250);
this.Load += new System.EventHandler(this.ValveCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox bitPositionTextBox;
private System.Windows.Forms.Label bitPositionLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.Label inputsCountLabel;
private System.Windows.Forms.TextBox inputsCountTextBox;
private System.Windows.Forms.Label logicalOpLabel;
private System.Windows.Forms.ComboBox logicalOpComboBox;
private System.Windows.Forms.CheckBox invertedOutpCheckBox;
private System.Windows.Forms.ComboBox input1ComboBox;
private System.Windows.Forms.Label input1Label;
private System.Windows.Forms.ComboBox input2ComboBox;
private System.Windows.Forms.Label input2Label;
private System.Windows.Forms.ComboBox input3ComboBox;
private System.Windows.Forms.Label input3Label;
private System.Windows.Forms.ComboBox input4ComboBox;
private System.Windows.Forms.Label input4Label;
private System.Windows.Forms.ComboBox input5ComboBox;
private System.Windows.Forms.Label input5Label;
}
}
+185
View File
@@ -0,0 +1,185 @@
///
/// Copyright (c) 2015 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
namespace TBF.Rig.BuiltIn.ValveEx
{
public partial class ValveCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
public bool ShowMore { get { return false; } }
ValveCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as ValveCfg;
Redraw();
}
}
public ValveCfgCtrl()
{
InitializeComponent();
}
private void ValveCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
logicalOpComboBox.Items.Add("AND");
logicalOpComboBox.Items.Add("OR");
if (parent.CmpntEntities != null)
{
AddValvePumpItemsToCombo(input1ComboBox, parent.CmpntEntities);
AddValvePumpItemsToCombo(input2ComboBox, parent.CmpntEntities);
AddValvePumpItemsToCombo(input3ComboBox, parent.CmpntEntities);
AddValvePumpItemsToCombo(input4ComboBox, parent.CmpntEntities);
AddValvePumpItemsToCombo(input5ComboBox, parent.CmpntEntities);
}
Redraw();
}
void AddValvePumpItemsToCombo(ComboBox combo, IList<Config.Entities.Component> components)
{
foreach (var cmpntEntity in components)
{
IComponent comp = TbfComponents.CmpntFactoryFromClassName(cmpntEntity.ClassName).DummyComponent();
if (comp is GenericDevices.IValve )
{
combo.Items.Add(cmpntEntity.Name);
}
}
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
bitPositionTextBox.Text = config.BitPosition.ToString();
invertedOutpCheckBox.Checked = config.InvertOutput;
logicalOpComboBox.Text = (config.LogicalOp == ValveExOperation.And) ? "AND" : ((config.LogicalOp == ValveExOperation.Or) ? "OR" : "---");
inputsCountTextBox.Text = config.InputValvesCount.ToString();
input1ComboBox.Text = config.Input1;
input2ComboBox.Text = config.Input2;
input3ComboBox.Text = config.Input3;
input4ComboBox.Text = config.Input4;
input5ComboBox.Text = config.Input5;
}
public void Unlock()
{
nameTextBox.Enabled = true;
bitPositionTextBox.Enabled = true;
invertedOutpCheckBox.Enabled = true;
logicalOpComboBox.Enabled = true;
inputsCountTextBox.Enabled = true;
input1ComboBox.Enabled = true;
input2ComboBox.Enabled = true;
input3ComboBox.Enabled = true;
input4ComboBox.Enabled = true;
input5ComboBox.Enabled = true;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.BitPosition = int.Parse(bitPositionTextBox.Text);
config.InvertOutput = invertedOutpCheckBox.Checked;
config.LogicalOp = (logicalOpComboBox.Text == "AND") ? ValveExOperation.And : ValveExOperation.Or;
config.InputValvesCount = int.Parse(inputsCountTextBox.Text);
config.Input1 = input1ComboBox.Text.Equals("---") ? string.Empty : input1ComboBox.Text;
config.Input2 = input2ComboBox.Text.Equals("---") ? string.Empty : input2ComboBox.Text;
if (config.InputValvesCount >= 3) config.Input3 = input3ComboBox.Text.Equals("---") ? string.Empty : input3ComboBox.Text;
if (config.InputValvesCount >= 4) config.Input4 = input4ComboBox.Text.Equals("---") ? string.Empty : input4ComboBox.Text;
if (config.InputValvesCount >= 5) config.Input5 = input5ComboBox.Text.Equals("---") ? string.Empty : input5ComboBox.Text;
return flags;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
int dummy;
if (!int.TryParse(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 128)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 127";
}
if (!logicalOpComboBox.Items.Contains(logicalOpComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Category'";
}
int nrInputs;
if (!int.TryParse(inputsCountTextBox.Text, out nrInputs) || nrInputs < 2 || nrInputs > 5)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Inputs count' out of range (2..5)";
}
if (!input1ComboBox.Items.Contains(input1ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Input 1'";
}
if (!input2ComboBox.Items.Contains(input2ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Input 2'";
}
if (nrInputs >= 3 && !input3ComboBox.Items.Contains(input3ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Input 3'";
}
if (nrInputs >= 4 && !input4ComboBox.Items.Contains(input4ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Input 4'";
}
if (nrInputs >= 5 && !input5ComboBox.Items.Contains(input5ComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Input 5'";
}
return flags;
}
private void inputsCountTextBox_TextChanged(object sender, EventArgs e)
{
int count;
if (int.TryParse(inputsCountTextBox.Text, out count) && count >= 2 || count <= 5)
{
input3Label.Visible = (count >= 3);
input4Label.Visible = (count >= 4);
input5Label.Visible = (count >= 5);
input3ComboBox.Visible = (count >= 3);
input4ComboBox.Visible = (count >= 4);
input5ComboBox.Visible = (count >= 5);
}
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+27
View File
@@ -0,0 +1,27 @@
///
/// Copyright (c) 2015-2016 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.BuiltIn.ValveEx
{
public class ValveFactory : IComponentFactory
{
public string ClassName { get { return "ValveEx"; } }
public override string ToString() { return ClassName; }
public void ResetStaticProperties() { Valve.ResetStaticProperties(); }
public IComponent DummyComponent() { return new Valve(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Valve(cfg, components); }
public IComponentCfg DefaultConfig() { return new ValveCfg(this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(ValveCfg.Serializer, component, this);
}
}
}