Initial commit almost identical to SVN-repo rev.340

This commit is contained in:
Milan Hanajik
2014-07-28 09:56:40 +02:00
commit 175a92f633
575 changed files with 186534 additions and 0 deletions
@@ -0,0 +1,71 @@
using System;
namespace TBF.BenchControl.Elde
{
public enum Command
{
None = 0, /// Do nothing, just transfer data (route, etc.)
Start = 1, /// Start the measurement
Stop = 2, /// Stop the measurement
}
public enum StatusP : ulong
{
RefFlowMeterMask = 0x7,
TestInProgress = 0x8,
TestCompleted = 0x10,
DiverterError = 0x20,
MsrmntWithDivrtr = 0x80,
RefPulsesMsrmnt = 0x100,
SynchroMethod = 0x800,
WaterMeterCalib = 0x1000,
EmgcyStopActive = 0x2000,
MsrmntGateActive = 0x4000,
TimeMeasurement = 0x8000,
FrequencyMeasured = 0x80000,
ADCError = 0x80000000,
TimeoutOccured = 0x100000000,
MeretAddresses = 0x200000000,
SampleBuferFull = 0x400000000,
ErrorTempMeter = 0x10000000000,
ErrorPressMeter1 = 0x1000000000000,
ErrorPressMeter2 = 0x2000000000000,
ErrorPressMeter3 = 0x4000000000000,
ErrorPressMeter4 = 0x8000000000000,
}
public enum StopDevs
{
None = 0,
Reference = 0x01,
Diverter = 0x02,
GatePulse = 0x08,
TimeMeasurement = 0x10,
BypassDevCoupled2Div = 0x20,
RegValveRegulation = 0x80,
All = 0xFF,
}
public enum TestMethods
{
Diverter = 0x01, /// 0x01 = Mass method (diverters are used), 0 = Volume method
FixedStart = 0x02,
Synchro = 0x04, /// 0x02 = Synchro method, 0 = Pulse counting
}
public enum RegulValveMode : byte
{
None = 0,
PulseWidth = 1, /// Pulse width 0.05 .. 2 sec.
TargetPosition = 2, /// Low and high position (=DAC value) limits (0..100%) are specified
TargetFrequency = 3, /// Low and high frequency limits (0..2000Hz,0..2200Hz) are specified
Stop = 4, /// Stop regulation
}
public enum RegulValveState
{
Idle = 0,
PwOrFreqRegul = 2,
DacValueRegul = 3,
}
}
@@ -0,0 +1,52 @@
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde
{
public class ControlBoardCfg : ComponentCfgBase, IComponentCfg
{
public int ComPortNr;
/// Parameterless constructor
public ControlBoardCfg()
{
}
/// Constructor
public ControlBoardCfg(IComponentFactory factory, string name, int comPortNr)
: base(factory, name)
{
this.ComPortNr = comPortNr;
}
public IComponentCfg Clone()
{
return new ControlBoardCfg(Factory, Name, ComPortNr);
}
public string ToString(int i)
{
return string.Format("COM{0}", ComPortNr);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component tbfComponent, IComponentFactory factory)
{
using (var reader = new StringReader(tbfComponent.Parameters))
{
ControlBoardCfg config = (ControlBoardCfg)(new XmlSerializer(typeof(ControlBoardCfg))).Deserialize(reader);
config.Name = tbfComponent.Name;
config.InitCfgBaseFromEntity(tbfComponent, factory);
return config;
}
}
}
}
@@ -0,0 +1,106 @@
namespace TBF.BenchControl.Elde
{
partial class ControlBoardCfgCtrl
{
/// <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.label1 = new System.Windows.Forms.Label();
this.comPortNrTextBox = new System.Windows.Forms.TextBox();
this.classNameLabel = new System.Windows.Forms.Label();
this.nameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(44, 113);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(98, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Serial Port Number:";
//
// comPortNrTextBox
//
this.comPortNrTextBox.Enabled = false;
this.comPortNrTextBox.Location = new System.Drawing.Point(154, 110);
this.comPortNrTextBox.Name = "comPortNrTextBox";
this.comPortNrTextBox.Size = new System.Drawing.Size(105, 20);
this.comPortNrTextBox.TabIndex = 1;
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(151, 45);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 2;
this.classNameLabel.Text = "ComonentName";
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(44, 79);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 3;
this.nameLabel.Text = "Name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(154, 76);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(105, 20);
this.nameTextBox.TabIndex = 4;
//
// ControlBoardCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Controls.Add(this.comPortNrTextBox);
this.Controls.Add(this.label1);
this.Name = "ControlBoardCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.ControlBoardCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox comPortNrTextBox;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.TextBox nameTextBox;
}
}
@@ -0,0 +1,75 @@
using System;
using System.Windows.Forms;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde
{
public partial class ControlBoardCfgCtrl : UserControl, IComponentCfgCtrl
{
ControlBoardCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as ControlBoardCfg;
Redraw();
}
}
public ControlBoardCfgCtrl()
{
InitializeComponent();
}
private void ControlBoardCfgCtrl_Load(object sender, EventArgs e)
{
Redraw();
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
comPortNrTextBox.Text = config.ComPortNr.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
comPortNrTextBox.Enabled = true;
}
/// <summary>
/// Verify current user controls for validity.
/// Called when user wants to close/save the configuration.
/// </summary>
/// <returns>See VerifyFlags</returns>
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!int.TryParse(comPortNrTextBox.Text, out dummy) || dummy <= 0 || dummy > 999)
{
message += "Control board serial port number is invalid";
flags |= CfgVerifyFlags.Error;
}
return flags;
}
/// <summary>
/// Save settings to the configuration class.
/// </summary>
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
///
this.Name = nameTextBox.Text;
this.config.ComPortNr = int.Parse(comPortNrTextBox.Text);
}
}
}
@@ -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>
@@ -0,0 +1,334 @@
using System;
using System.Text;
using System.IO.Ports;
using System.Collections.Generic;
using TBF.BenchControl.Generic;
using TBF.BenchControl.GenericDevices;
using log4net;
namespace TBF.BenchControl.Elde
{
public class ControlBoardDev : IComponent, IDevice, IValveControl
{
/// <summary>
/// Info:
/// Warn:
/// Error:
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(ControlBoardDev));
public override string ToString() { return string.Format("ControlBoardDev on com{0}", controlBoardCfg.ComPortNr); }
public static void ResetStaticProperties() { }
ControlBoardCfg controlBoardCfg;
public Generic.IComponentCfg Cfg { get { return controlBoardCfg; } }
public string Name { get { return controlBoardCfg.Name; } }
///
/// Reference to the control board component
///
IControlCom controlCom;
/// <summary>
/// Emergency stop signal state updated by RunDevice().
/// 'modelessDlg' is notified about the changes and uses this information to change its visibility.
/// </summary>
//UiBridge.EmergencyStopEventArgs.State emergencyStopState;
///
/// Public read only wrappers for Elde software component fields
///
/// rvNr1 = 1 .. nrRegulValves (one based)
/// wmNr0 = 0 .. nrWaterMeters-1 (zero based)
/// tmpNr0 = 0 .. nrTempMeters-1 (zero based)
/// prsNr0 = 0 .. nrPressureMeters-1 (zero based)
///
public StatusP StatusP { get { return controlCom.StatusP; } }
public float ReferenceFreq { get { return controlCom.ReferenceFreq; } } /// In [Hz] 0..2500, nom.=2000
public int EtPulses(int wmNr0) { return controlCom.EtPulses(wmNr0); }
public int WMeterPulses(int wmNr0) { return controlCom.WMeterPulses(wmNr0); }
public int WMeterReference(int wmNr0) { return controlCom.WMeterReference(wmNr0); }
public uint RegulValveDAC { get { return controlCom.RegulValveDAC; } }
public float Pressure(int prsNr0) { return controlCom.Pressure(prsNr0); }
public float Temperature(int tmpNr0) { return controlCom.Temperature(tmpNr0); }
public RegulValveState RegulValveState(int rvNr1) { return (RegulValveState)controlCom.RegulValveState(rvNr1); }
public ulong RRoute { get { return controlCom.RRoute; } }
public uint DivTime { get { return controlCom.DivTime; } }
public float TTime { get { return controlCom.TTime; } }
public uint FmState { get { return controlCom.FmState; } }
public uint BeginState(int wmNr0) { return controlCom.BeginState(wmNr0); }
public float ReferenceFlow { get { return controlCom.ReferenceFlow; } }
public float RValvePosition(int rvNr1) { return controlCom.RValvePosition(rvNr1); }
public float DivSamples(int ms) { return controlCom.DivSamples(ms); }
public int ScopeSamples(int i, int j, int k) { return controlCom.ScopeSamples(i, j, k); }
public uint DigitalInputs { get { return controlCom.DigitalInputs; } }
public float AnalogInput(int adcNr0) { return controlCom.AnalogInput(adcNr0); }
public uint AnalogInputRaw(int adcNr0, int bank) { return controlCom.AnalogInputRaw(adcNr0, bank); } /// bank0=RV, bank1=Temp
public float ReferenceVolume { get { return controlCom.ReferenceVolume; } }
public float VyslExt(int wmNr0, int what) { return controlCom.VyslExt(wmNr0, what); }
/// <summary> Extracted from the StatusP </summary>
public bool EmgcyStopActive { get { return (controlCom.StatusP & StatusP.EmgcyStopActive) != 0; } }
/// <summary> State of valves sent out - buffered by the last SendCommand() </summary>
public ulong Route { get { return route; } }
///
/// Initialization data updated by constructors of children components
/// and sent to 'controlCom2panel' by SendCalibData() method.
///
public uint[,] RegValveCalib = new uint[8, 2];
public byte[] MeretRS485Address = new byte[4];
public float[,] TempCalibData = new float[8, 5];
// Array length is the reference flowmeters count plus one
#if DN100
public float[] EtCalib = new float[6] { 1, 1, 1, 1, 1, 1 };
#elif MUNICH
public float[] EtCalib = new float[5] { 1, 1, 1, 1, 1 };
#elif FUZHOU150
public float[] EtCalib = new float[6] { 1, 1, 1, 1, 1, 1 };
#endif
public uint[] DiverterEdge = new uint[2] { 50, 50 };
public uint[] BalanceRange = new uint[2];
///
/// Private values sent by the last SendCommand()
///
bool sendCommandFlag;
Command cmd;
int refNr;
ulong route;
int refPulses;
TestMethods testMethods;
float filterConstant;
float[] FMFreq;
int regConst;
int shortImp;
StopDevs stopDevs;
public void SetFMFreq(int index, float power)
{
if (index == 0) FMFreq = new float[2] { power, 0 };
else if (index == 1) FMFreq = new float[2] { 0, power };
else FMFreq = new float[2] { 0, 0 };
}
public void UpdateWeights()
{
for (int i = 0; i < MettlerToledo.BalanceDev.BalancesCount; i++)
{
controlCom.SetWeight(i, MettlerToledo.BalanceDev.Masses[i]);
}
}
/// <summary>
/// Constructor
/// </summary>
public ControlBoardDev(ControlBoardCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.controlBoardCfg = cfg;
FMFreq = new float[2] { 0, 0 };
}
/// <summary>
/// Specific pre-initialization for control board only
/// </summary>
/// <param name="ctrlBrdComponent"></param>
public void InitializeComponent(
#if DN100
ControlCom2VB.ControlCom2panel ctrlBrdComponent,
#elif MUNICH
ControlComponent3Munich.UserControl1 ctrlBrdComponent,
#elif FUZHOU150
ControlComponent3Munich.UserControl1 ctrlBrdComponent,
#endif
float[] tankCapacities)
{
if (controlBoardCfg.DebugLevel == Entities.DebugMode.Simulate)
{
controlCom = new ControlComSim();
}
else
{
int cnt = Math.Min(BalanceRange.Length, tankCapacities.Length);
for (int i = 0; i < cnt; i++) BalanceRange[i] = (uint)tankCapacities[i];
controlCom = new ControlComWrap(ctrlBrdComponent);
}
}
/// <summary>Initialize this device</summary>
public void Initialize()
{
controlCom.SendCalibData(RegValveCalib,
MeretRS485Address,
controlBoardCfg.ComPortNr,
TempCalibData,
EtCalib,
DiverterEdge,
BalanceRange);
}
/// <summary>Run this device</summary>
public void RunDeviceBefore()
{
controlCom.RunDeviceBefore();
if (EmgcyStopActive)
{
/// SendCommand() arguments to clear the emergency stop state
sendCommandFlag = true;
this.cmd = Command.Stop;
this.stopDevs = StopDevs.All;
}
else
{
/// Reset all SendCommand() arguments
sendCommandFlag = false;
this.cmd = Command.None;
this.stopDevs = 0;
}
this.refNr = 0;
this.refPulses = 0;
this.testMethods = 0;
this.filterConstant = 0;
this.regConst = 0;
this.shortImp = 0;
}
/// <summary>Run this device</summary>
public void RunDeviceAfter()
{
if (sendCommandFlag)
{
controlCom.SendCommand(cmd, refNr, route, refPulses, testMethods,
filterConstant, FMFreq, regConst, shortImp, stopDevs);
}
controlCom.RunDeviceAfter();
}
/// <summary>Stop this device</summary>
public void StopDevice()
{
}
/// <summary>
/// Sends a command to the control board.
/// </summary>
/// <param name="cmd">See ControlBoard.Command enum</param>
/// <param name="refFlowmtrNr">Number of the etalon/reference (1..5)</param>
/// <param name="route">Route: 64-bit installation specific number</param>
/// <param name="totalRefPulses">kolko impulzov ma trvat skuska</param>
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
/// <param name="filterConstant">0 = No filtering (0..255)</param>
/// <param name="regConst">Coefficient used to control reg. valves (1..100)</param>
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
/// <param name="stopDevs">What to stop</param>
public void SendCommand(Command cmd, int refFlowmtrNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, int regConst, int shortImp, StopDevs stopDevs)
{
this.cmd = cmd;
this.refNr = refFlowmtrNr;
this.route = route;
this.refPulses = totalRefPulses;
this.testMethods = testMethods;
this.filterConstant = filterConstant;
this.regConst = regConst;
this.shortImp = shortImp;
this.stopDevs = stopDevs;
sendCommandFlag = true;
}
public void SetValves(ulong valvesToOpen, ulong valvesToClose)
{
route = (route | valvesToOpen) & (~valvesToClose);
sendCommandFlag = true;
}
/// <summary>
/// Regulation valves control.
/// </summary>
/// <param name="valveNo">Regulation valve nr. (1..5)</param>
/// <param name="valveMode">Valve regulation mode, see the enum</param>
/// <param name="valveValue">Target position or target frequency or pulse duration</param>
public void ValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue)
{
controlCom.ValveMove(valveNo, valveMode, valveValue);
}
/// <summary>
/// Open one valve and/or close one valve.
/// Events: ValvesSet
/// </summary>
/// <param name="valveOpen">Valve to be opened</param>
/// <param name="valveClose">Valve to be closed</param>
/// <returns>Created operation</returns>
public IOperation SetValvesOp(IValve valveOpen, IValve valveClose)
{
return new Valve.SetValvesOp(this, valveOpen, valveClose);
}
/// <summary>
/// Open and/or close multiple valves.
/// Events: ValvesSet
/// </summary>
/// <param name="valvesOpen">A list of valves to be opened</param>
/// <param name="valvesClose">A list of valves to be closed</param>
/// <returns>Created operation</returns>
public IOperation SetValvesOp(IList<IValve> valvesOpen, IList<IValve> valvesClose)
{
return new Valve.SetValvesOp(this, valvesOpen, valvesClose);
}
/// <summary>
/// Starts the measurement.
/// Events: MeasurementStarted
/// </summary>
/// <param name="flowMeter">Flow meter</param>
/// <param name="readers">An array of register readers</param>
/// <param name="refPulses">Number of reference pulses to complete the test</param>
/// <returns>Created operation</returns>
public IOperation StartMeasurementOp(IFlowMeter flowMeter, int refPulses, TestMethods method)
{
return new StartMeasurementOp(this, flowMeter, refPulses, method);
}
/// <summary>
/// Queries th econtrol board whether the measurement was completed.
/// Events: MeasurementCompleted or None
/// </summary>
/// <returns>Created operation</returns>
public IOperation QueryMeasurementEndOp()
{
return new QueryMeasurementEndOp(this);
}
/// <summary>
/// Stop the previous control board operation (diverter, gate, etc.)
/// Events: PreviousStopped
/// </summary>
/// <returns>Created operation</returns>
public IOperation StopPreviousOp()
{
return new StopPreviousOp(this);
}
/// <summary>
/// Updates the tank drawing and weight value in Elde software component.
/// </summary>
/// <param name="weight">Current mass in [kg] or approx. volume in [l]</param>
/// <returns>Created operation</returns>
public IOperation UpdateTankWeightOp()
{
return new UpdateTankWeightOp(this);
}
}
}
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde
{
public class ControlBoardFactory : IComponentFactory
{
public string ClassName { get { return "ControlBoard"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 1; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new ControlBoardCfg(this, "CB", 1);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new ControlBoardCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new ControlBoardDev((ControlBoardCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return Elde.ControlBoardCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { ControlBoardDev.ResetStaticProperties(); }
}
}
@@ -0,0 +1,293 @@
using System;
using System.Collections.Generic;
using System.Text;
using log4net;
namespace TBF.BenchControl.Elde
{
public class ControlComSim : TestBenchSim, IControlCom
{
private static readonly ILog log = LogManager.GetLogger(typeof(ControlComSim));
public override string ToString() { return string.Format("ControlComSim"); }
StatusP statusP;
public StatusP StatusP { get { return statusP; } }
float referenceFreq = 650.0f;
public float ReferenceFreq { get { return referenceFreq; } }
int[] etPulses = new int[Program.WMsCount + 1];
public int EtPulses(int wmNr1and0)
{
return etPulses[wmNr1and0];
}
float[] errFactor = new float[Program.WMsCount + 1]; /// Internal
float[] wMeterPulsesF = new float[Program.WMsCount + 1]; /// Internal
int[] wMeterPulses = new int[Program.WMsCount + 1]; /// Rounded from wMeterPulsesF
public int WMeterPulses(int wmNr1)
{
return wMeterPulses[wmNr1];
}
int[] wMeterReference = new int[Program.WMsCount + 1];
public int WMeterReference(int wmNr1)
{
return wMeterReference[wmNr1];
}
public uint RegulValveDAC { get { return 0; } }
public float Pressure(int prsNr0) { return 0; }
public float Temperature(int tmpNr0) { return (float)(20 + tmpNr0); }
public RegulValveState RegulValveState(int rvNr1) { return 0; }
public ulong RRoute { get { return route; } }
public uint DivTime { get { return 0; } }
float tTime = 0;
public float TTime { get { return tTime; } }
public uint FmState { get { return 0; } }
public uint BeginState(int wmNr0) { return 0; }
float referenceFlow;
public float ReferenceFlow { get { return referenceFlow; } }
public float RValvePosition(int rvNr1) { return 0; }
public float DivSamples(int ms) { return 0; }
public int ScopeSamples(int i, int j, int k) { return 0; }
public uint DigitalInputs { get { return 0; } }
public float AnalogInput(int adcNr0) { return 0; }
public uint AnalogInputRaw(int adcNr0, int bank) { return 0; } /// bank0=RV, bank1=Temp
public float ReferenceVolume { get { return 0; } }
public float VyslExt(int wmNr0, int what) { return 0; }
public void SetWeight(int pos, float mass) { return; } /// not available in sim. mode
///
/// Private initialization data updated by contructors of children components
/// and sent to 'controlCom2panel' by SendCalibData() method.
///
uint[,] regValveCalib;
byte[] meretRS485Address;
float[,] tempCalibData;
float[] etCalib;
uint[] diverterEdge;
uint[] balanceRange;
///
/// Private values set by SendCommand()
///
Command cmd;
int refFlowmtrNr;
ulong route;
public ulong Route { get { return route; } }
int totalRefPulses;
TestMethods testMethods;
float filterConstant;
float[] FMFreq;
int regConst;
int shortImp;
StopDevs stopDevs;
///
/// Private values set by ValveMove()
///
int regulValveNo;
RegulValveMode regulValveMode;
float[] regulValveValue;
Random rand;
/// <summary>
/// Constructor
/// </summary>
public ControlComSim()
{
rand = new Random();
}
/// <summary>
/// Sends calibration and configuration data to the control board.
/// </summary>
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
/// <param name="etCalib">Etalon nominal values</param>
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
public void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib, float[] etCalib, uint[] divEdge, uint[] balanceRange)
{
this.regValveCalib = rvCalib;
this.meretRS485Address = meretA;
this.tempCalibData = tempCalib;
this.etCalib = etCalib;
this.diverterEdge = divEdge;
this.balanceRange = balanceRange;
}
/// <summary>
/// Sends a command to the control board.
/// </summary>
/// <param name="cmd">See ControlBoard.Command enum</param>
/// <param name="refFlowmtrNr">Number of the etalon/reference (1..5)</param>
/// <param name="route">Route: 64-bit installation specific number</param>
/// <param name="refPulses">kolko impulzov ma trvat skuska</param>
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
/// <param name="filterConstant">0 = No filtering (0..255)</param>
/// <param name="FMFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
/// <param name="regConst">Coefficient used to control reg. valves (1..100)</param>
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
/// <param name="stopDevs">What to stop</param>
public void SendCommand(Command cmd, int refFlowmtrNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] FMFreq, int regConst, int shortImp, StopDevs stopDevs)
{
Command lastCmd = this.cmd;
this.cmd = cmd;
this.refFlowmtrNr = refFlowmtrNr;
this.route = route;
RouteSim = route;
this.totalRefPulses = totalRefPulses;
this.testMethods = testMethods;
this.filterConstant = filterConstant;
this.FMFreq = FMFreq;
this.regConst = regConst;
this.shortImp = shortImp;
this.stopDevs = stopDevs;
statusP = (StatusP)(((ulong)statusP & 0xFFFFFFFFFFFFFFF8L) | (ulong)refFlowmtrNr);
if (cmd == Command.Start && lastCmd != Command.Start )
{
statusP |= StatusP.TestInProgress;
///
/// Clear all counters
///
if (etPulses != null) { for (int i = 0; i < etPulses.Length; i++) etPulses[i] = 0; }
if (wMeterPulses != null) { for (int i = 0; i < wMeterPulses.Length; i++) wMeterPulses[i] = 0; }
if (wMeterPulsesF != null) { for (int i = 0; i < wMeterPulsesF.Length; i++) wMeterPulsesF[i] = 0; }
if (wMeterReference != null) { for (int i = 0; i < wMeterReference.Length; i++) wMeterReference[i] = 0; }
if (errFactor != null)
{
for (int i = 0; i < errFactor.Length; i++) errFactor[i] = ((float)rand.Next(100) + 950.0f) / 1000.0f;
}
tTime = 0;
}
else if (cmd == Command.Stop)
{
statusP = 0;
//statusP &= ~StatusP.Running;
}
}
/// <summary>
/// Control of regulating valves.
/// </summary>
/// <param name="regulValveNo">Regulating valve nr. (1..5)</param>
/// <param name="regulValveMode">???</param>
/// <param name="regulValveValue">???</param>
public void ValveMove(int regulValveNo, RegulValveMode regulValveMode, float[] regulValveValue)
{
this.regulValveNo = regulValveNo;
this.regulValveMode = regulValveMode;
this.regulValveValue = regulValveValue;
}
public void RunDeviceBefore()
{
base.RunDevice(regulValveNo, refFlowmtrNr, statusP);
log.DebugFormat("refFreq=", referenceFreq);
tTime += 1.0f;
float Qnom = (regulValveNo > 0) ? etCalib[regulValveNo] : 0;
switch (cmd)
{
case Command.None:
break;
case Command.Start:
if ((testMethods & TestMethods.Diverter) == TestMethods.Diverter)
{
SetSimDiverter(true);
}
break;
case Command.Stop:
if ((testMethods & TestMethods.Diverter) == TestMethods.Diverter)
{
SetSimDiverter(false);
}
break;
}
switch (regulValveMode)
{
case RegulValveMode.TargetFrequency:
float targetFlow = ((regulValveValue[0] + regulValveValue[1]) / 2.0f) * (Qnom / 2000.0f);
UpdateSimFlow(targetFlow);
//if (referenceFreq < valveValue[0]) referenceFreq += ((float)rand.Next(20) + 10.0f) / 2.0f;
//else if (referenceFreq > valveValue[1]) referenceFreq -= ((float)rand.Next(20) + 10.0f) / 2.0f;
//else referenceFreq += ((float)rand.Next(10) - 5.0f) / 2.0f;
referenceFreq = GetSimFlow() * 2000.0f / Qnom;
if (referenceFreq < 0) referenceFreq = 0;
if (referenceFreq > 2500) referenceFreq = 2500;
break;
default:
break;
}
referenceFlow = referenceFreq / 2000;
bool stopTest = false;
if (cmd == Command.Start)
{
float pwFactor = 1.0f;
/// Increment reference flow meters
for (int i = 0; i < Program.WMsCount; i++)
{
etPulses[i] += (int)referenceFreq;
if (etPulses[i] > totalRefPulses)
{
pwFactor = 1.0f - (float)(etPulses[i] - totalRefPulses) / referenceFreq;
etPulses[i] = totalRefPulses;
stopTest = true;
}
}
/// Increment water meters
for (int i = 1; i < Program.WMsCount; i++)
{
const float wmPulsesPerLiter = 10.0f;
wMeterPulsesF[i] += errFactor[i] * pwFactor * ((float)rand.Next(100) + 450.0f) * wmPulsesPerLiter * GetSimFlow() / 1800.0f;
wMeterPulses[i] = (int)wMeterPulsesF[i];
}
if (etPulses[0] > totalRefPulses)
{
statusP |= StatusP.TestCompleted;
statusP &= ~StatusP.TestInProgress;
}
}
if (stopTest)
{
SetSimDiverter(false);
statusP = (statusP | StatusP.TestCompleted);
statusP = (statusP & ~StatusP.TestInProgress);
}
}
public void RunDeviceAfter()
{
}
}
}
@@ -0,0 +1,265 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class ControlComWrap : IControlCom
{
private static readonly ILog log = LogManager.GetLogger(typeof(ControlComWrap));
///
/// Properties
///
public StatusP StatusP { get { return (StatusP)ctrlBrdComponent.StatusP; } }
public float ReferenceFreq { get { return 1000.0f * ctrlBrdComponent.referenceFreq; } } /// In [Hz] 0..2500, nom.=2000
public int EtPulses(int wmNr0)
{
return (int)ctrlBrdComponent.etPulses[wmNr0];
}
public int WMeterPulses(int wmNr0)
{
return (int)ctrlBrdComponent.wMeterPuls[wmNr0];
}
public int WMeterReference(int wmNr0) { return (int)ctrlBrdComponent.wMeterReference[wmNr0]; }
public uint RegulValveDAC { get { return ctrlBrdComponent.StavDA; } }
public float Pressure(int prsNr0) { return ctrlBrdComponent.pressure[prsNr0]; }
public float Temperature(int tmpNr0) { return ctrlBrdComponent.temperature[tmpNr0]; }
public RegulValveState RegulValveState(int rvNr1) { return (RegulValveState)ctrlBrdComponent.rValveStatus[rvNr1 - 1]; }
public ulong RRoute { get { return ctrlBrdComponent.rRoute; } }
public uint DivTime { get { return ctrlBrdComponent.divTime; } }
public float TTime { get { return ctrlBrdComponent.Ttime; } }
public uint FmState { get { return ctrlBrdComponent.fMState; } }
public uint BeginState(int wmNr0) { return ctrlBrdComponent.beginSt[wmNr0]; }
public float ReferenceFlow { get { return ctrlBrdComponent.referenceFlow; } }
public float RValvePosition(int rvNr1)
{
//return ctrlBrdComponent.RValvePosition[rvNr1 - 1];
return ctrlBrdComponent.Analogy[rvNr1 - 1]; /// Fixes bug: RValvePosition returns 0 all the time
}
public float DivSamples(int ms) { return ctrlBrdComponent.DIVSamples[ms, 0]; }
public int ScopeSamples(int i, int j, int k) { return ctrlBrdComponent.ScopeSamples[i, j, k]; }
public uint DigitalInputs { get { return ctrlBrdComponent.Vstupy; } }
public float AnalogInput(int adcNr0) { return ctrlBrdComponent.Analogy[adcNr0]; }
public uint AnalogInputRaw(int adcNr0, int bank) { return ctrlBrdComponent.AnalogyRaw[adcNr0, bank]; } /// bank0=RV, bank1=Temp
public float ReferenceVolume { get { return ctrlBrdComponent.ReferenceVolume; } }
public float VyslExt(int wmNr0, int what) { return ctrlBrdComponent.VyslExt[wmNr0, what]; }
public void SetWeight(int pos, float mass) { ctrlBrdComponent.Weight[pos] = mass; }
///
/// Reference to the control board component
///
#if DN100
private ControlCom2VB.ControlCom2panel ctrlBrdComponent;
#elif MUNICH
private ControlComponent3Munich.UserControl1 ctrlBrdComponent;
#elif FUZHOU150
private ControlComponent3Munich.UserControl1 ctrlBrdComponent;
#endif
/// <summary>
/// Constructor that initializes the control board component reference
/// </summary>
/// <param name="ctrlBrdComponent"></param>
#if DN100
public ControlComWrap(ControlCom2VB.ControlCom2panel ctrlBrdComponent)
#elif MUNICH
public ControlComWrap(ControlComponent3Munich.UserControl1 ctrlBrdComponent)
#elif FUZHOU150
public ControlComWrap(ControlComponent3Munich.UserControl1 ctrlBrdComponent)
#endif
{
this.ctrlBrdComponent = ctrlBrdComponent;
}
/// <summary>
/// Sends calibration and configuration data to the control board.
/// </summary>
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
/// <param name="etCalib">Etalon nominal values</param>
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
/// <param name="balanceRange">Balance range = volume of the tanks on the balaces (ix=0,1)</param>
public void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib,
float[] etCalib, uint[] divEdge, uint[] balanceRange)
{
if (Program.MainWnd.InvokeRequired)
{
/// When SendCalibData(...) called from the worker thread
object[] args = new object[] { rvCalib, meretA, usedCom, tempCalib, etCalib, divEdge, balanceRange };
Program.MainWnd.Invoke((SendCalibDataDlgt)DoSendCalibData, args); /// Invoke required as component was created in UI thread
}
else
{
/// When SendCalibData(...) called from the UI thread
DoSendCalibData(rvCalib, meretA, usedCom, tempCalib, etCalib, divEdge, balanceRange);
}
}
///
delegate void SendCalibDataDlgt(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib,
float[] etCalib, uint[] divEdge, uint[] balanceRange);
///
private void DoSendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib,
float[] etCalib, uint[] divEdge, uint[] balanceRange)
{
//TBF.UiBridge.Bridge.OnLog(this, string.Format("{0} SendCalibData(COM{1}) rvCalib[0,0]={2} rvCalib[0,1]={3} rvCalib[1,0]={4} rvCalib[1,1]={5}\r\n",
// DateTime.Now.ToLongTimeString(), usedCom,
// rvCalib[0,0], rvCalib[0,1], rvCalib[1,0], rvCalib[1,1]));
log.InfoFormat("SendCalibData(COM{0}) rvCalib[0,0]={1} rvCalib[0,1]={2} rvCalib[1,0]={3} rvCalib[1,1]={4}\r\n",
usedCom, rvCalib[0,0], rvCalib[0,1], rvCalib[1,0], rvCalib[1,1]);
#if (DN100)
ctrlBrdComponent.ExternalCom = true;
#endif
ctrlBrdComponent.SendCalibData(rvCalib, meretA, (byte)usedCom, tempCalib, etCalib, divEdge, balanceRange);
}
/// <summary>
/// Control of regulating valves.
/// </summary>
/// <param name="valveNo">Regulating valve nr. (1..5)</param>
/// <param name="valveMode">Valve regulation mode, see the enum</param>
/// <param name="valveValue">Target position or target frequency or pulse duration</param>
public void ValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue)
{
if (Program.MainWnd.InvokeRequired)
{
/// When ValveMove(...) called from the worker thread
object[] args = new object[] { valveNo, valveMode, valveValue };
Program.MainWnd.Invoke((ValveMoveDlgt)DoValveMove, args); /// When ValveMove called from a worker thread
}
else
{
/// When ValveMove(...) called from the UI thread
DoValveMove(valveNo, valveMode, valveValue); /// When ValveMove called from the UI thread
}
}
///
delegate void ValveMoveDlgt(int valveNo, RegulValveMode valveMode, float[] valveValue);
///
private void DoValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue)
{
//TBF.UiBridge.Bridge.OnLog(this, string.Format("{0} ValveMove({1}, {2}, [{3}, {4}])\r\n",
// DateTime.Now.ToLongTimeString(),
// valveNo,
// valveMode,
// valveValue[0],
// valveValue[1]));
log.InfoFormat("ValveMove({0}, {1}, [{2}, {3}])\r\n", valveNo, valveMode, valveValue[0], valveValue[1]);
ctrlBrdComponent.ValveMove((byte)valveNo, (byte)valveMode, valveValue);
}
/// <summary>
/// Sends a command to the control board.
/// </summary>
/// <param name="cmd">See ControlBoard.Command enum</param>
/// <param name="refFlowMeterNr">Reference flow meter number (1..5)</param>
/// <param name="route">Route: 64-bit installation specific number</param>
/// <param name="refPulses">Test duration as a number of reference flow meter pulses</param>
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
/// <param name="filterConstant">0 = No filtering (0..255)</param>
/// <param name="FMFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
/// <param name="regConst">Coefficient used to control the regulation valve (1..100)</param>
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
/// <param name="stopDevs">What to stop</param>
public void SendCommand(Command cmd, int refFlowMeterNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs)
{
if (Program.MainWnd.InvokeRequired)
{
/// When SendCommand(...) called from the worker thread
object[] args = new object[] { cmd, refFlowMeterNr, route, totalRefPulses, testMethods,
filterConstant, fmFreq, regConst, shortImp, stopDevs };
Program.MainWnd.Invoke((SendCommandDlgt)DoSendCommand, args); /// Component was created in UI thread - use Invoke()
}
else
{
/// When SendCommand(...) called from the UI thread
DoSendCommand(cmd, refFlowMeterNr, route, totalRefPulses, testMethods,
filterConstant, fmFreq, regConst, shortImp, stopDevs);
}
}
///
delegate void SendCommandDlgt(Command cmd, int refFlowmtrNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs);
///
private void DoSendCommand(Command cmd, int refFlowMeterNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs)
{
//TBF.UiBridge.Bridge.OnLog(this, string.Format("{0} SendCommand({1}, {2}, {3}, {4}, {5}, {6}, [{7},{8}], {9}, {10}, {11})\r\n",
// DateTime.Now.ToLongTimeString(),
// cmd,
// refFlowMeterNr,
// route.ToString("X"),
// totalRefPulses,
// testMethods,
// filterConstant,
// fmFreq[0],
// fmFreq[1],
// regConst,
// shortImp,
// stopDevs));
log.InfoFormat("SendCommand({0}, {1}, {2}, {3}, {4}, {5}, [{6},{7}], {8}, {9}, {10})\r\n",
cmd,
refFlowMeterNr,
route.ToString("X"),
totalRefPulses,
testMethods,
filterConstant,
fmFreq[0],
fmFreq[1],
regConst,
shortImp,
stopDevs);
#if DN100
ctrlBrdComponent.SendCommand((uint)cmd, (byte)refFlowMeterNr, (ulong)route, (uint)totalRefPulses, (uint)testMethods,
filterConstant, fmFreq[0], (uint)regConst, (uint)shortImp, (uint)stopDevs);
#else
ctrlBrdComponent.SendCommand((uint)cmd, (byte)refFlowMeterNr, (ulong)route, (uint)refPulses, (uint)testMethods,
filterConstant, FMFreq, (uint)regConst, (uint)shortImp, (uint)stopDevs);
#endif
}
enum CommType
{
Rx, /// Receive data only
TxRx, /// Transmit and receive data
}
public void RunDeviceBefore()
{
object[] args = new object[] { CommType.Rx };
MakeCommDlgt dlgt = MakeComm;
Program.MainWnd.Invoke(dlgt, args); /// Invoke MakeExtComm(.) in the UI thread
}
public void RunDeviceAfter()
{
object[] args = new object[] { CommType.TxRx };
MakeCommDlgt dlgt = MakeComm;
Program.MainWnd.Invoke(dlgt, args); /// Invoke MakeExtComm(.) in the UI thread
}
/// <summary>
/// A delegate to execute the SendCommand() in the UI thread
/// </summary>
delegate void MakeCommDlgt(CommType extComm);
/// <summary>
/// Executes the SendCommand(...) and MakeExtCom() in the UI thread
/// </summary>
void MakeComm(CommType commType)
{
if (ctrlBrdComponent.ExternalCom)
{
ctrlBrdComponent.MakeExtCom((commType == CommType.Rx) ? false : true);
}
}
}
}
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using log4net;
namespace TBF.BenchControl.Elde.Diverter
{
public class Diverter : Generic.IComponent, GenericDevices.IDiverter
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(Diverter));
public override string ToString()
{
return string.Format("Diverter({0},{1})", Name, diverterCfg.BitPosition);
}
public static void ResetStaticProperties() { }
private readonly DiverterCfg diverterCfg;
public Generic.IComponentCfg Cfg { get { return diverterCfg; } }
public string Name { get { return diverterCfg.Name; } }
readonly ControlBoardDev controlBoard;
public readonly ulong Mask; /// derived from bitPosition in the constructor
public Diverter(DiverterCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.diverterCfg = cfg;
controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
if (cfg.BitPosition < 0 || cfg.BitPosition >= 64) throw new ArgumentOutOfRangeException("position");
this.Mask = (((ulong)1) << cfg.BitPosition);
log.Debug(this.ToString());
}
public bool State
{
get { return (controlBoard.Route & Mask) != 0; }
}
}
}
@@ -0,0 +1,51 @@
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Diverter
{
public class DiverterCfg : ComponentCfgBase, IChildComponentCfg
{
public int BitPosition;
/// Parameterless constructor
public DiverterCfg()
{
}
/// Constructor
public DiverterCfg(IComponentFactory factory, string name, string parentName, int bitPosition)
: base(factory, name, parentName)
{
this.BitPosition = bitPosition;
}
public IComponentCfg Clone()
{
return new DiverterCfg(Factory, Name, ParentName, BitPosition);
}
public string ToString(int i)
{
return string.Format("bit={0}", BitPosition);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
DiverterCfg config = (DiverterCfg)(new XmlSerializer(typeof(DiverterCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,130 @@
namespace TBF.BenchControl.Elde.Diverter
{
partial class DiverterCfgCtrl
{
/// <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.parentNameLabel = new System.Windows.Forms.Label();
this.bitPositionLabel = new System.Windows.Forms.Label();
this.bitPositionTextBox = new System.Windows.Forms.TextBox();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(137, 41);
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(27, 44);
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(134, 17);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(27, 70);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent Name";
//
// bitPositionLabel
//
this.bitPositionLabel.AutoSize = true;
this.bitPositionLabel.Location = new System.Drawing.Point(27, 96);
this.bitPositionLabel.Name = "bitPositionLabel";
this.bitPositionLabel.Size = new System.Drawing.Size(59, 13);
this.bitPositionLabel.TabIndex = 5;
this.bitPositionLabel.Text = "Bit Position";
//
// bitPositionTextBox
//
this.bitPositionTextBox.Enabled = false;
this.bitPositionTextBox.Location = new System.Drawing.Point(137, 93);
this.bitPositionTextBox.Name = "bitPositionTextBox";
this.bitPositionTextBox.Size = new System.Drawing.Size(46, 20);
this.bitPositionTextBox.TabIndex = 6;
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(137, 67);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// DiverterCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
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 = "DiverterCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.DiverterCfgCtrl_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.Label parentNameLabel;
private System.Windows.Forms.Label bitPositionLabel;
private System.Windows.Forms.TextBox bitPositionTextBox;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,89 @@
using System;
using System.Windows.Forms;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Diverter
{
public partial class DiverterCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
DiverterCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as DiverterCfg;
Redraw();
}
}
public DiverterCfgCtrl()
{
InitializeComponent();
}
private void DiverterCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
nameTextBox.Text = config.Name;
bitPositionTextBox.Text = config.BitPosition.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
bitPositionTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 64)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 63";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.BitPosition = int.Parse(bitPositionTextBox.Text);
}
}
}
@@ -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>
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Diverter
{
public class DiverterFactory : IComponentFactory
{
public string ClassName { get { return "Diverter"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 5; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new DiverterCfg(this, "Diverter", "CB", 0);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new DiverterCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new Diverter((DiverterCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return DiverterCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { Diverter.ResetStaticProperties(); }
}
}
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using log4net;
namespace TBF.BenchControl.Elde.FlowMeter
{
public class FlowMeter : Generic.IComponent, GenericDevices.IFlowMeter
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
public override string ToString()
{
return string.Format("FlowMeter({0},{1})", Name, Position);
}
public static void ResetStaticProperties() { }
FlowMeterCfg flowMeterCfg;
public Generic.IComponentCfg Cfg { get { return flowMeterCfg; } }
public string Name { get { return flowMeterCfg.Name; } }
public IList<Entities.MeasurementCorrection> Corrections { get { return flowMeterCfg.Corrections; } }
public readonly ControlBoardDev ControlBoard;
public readonly int Position; /// 1..4
readonly float nominalFlow;
public float NominalFlow { get { return nominalFlow; } }
public FlowMeter(FlowMeterCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.flowMeterCfg = cfg;
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
Position = cfg.Position;
nominalFlow = cfg.NominalFlow;
ControlBoard.EtCalib[Position] = NominalFlow;
/// Prepare data for SendCalibData() control board component method
log.Debug(this.ToString());
}
/// <summary>
/// Events: FlowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref FloatBox flow)
{
return new ReadFlowOp(this, ref flow);
}
/// <summary>
/// Events: flowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <param name="flowDone">Event returned when measurement done</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref FloatBox flow, Event flowDone)
{
return new ReadFlowOp(this, ref flow, flowDone);
}
}
}
@@ -0,0 +1,61 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.FlowMeter
{
public class FlowMeterCfg : ComponentCfgBase, Generic.IChildComponentCfg
{
public int Position; /// 1..5
public float NominalFlow; /// Nominal flow in m3/h at output frequency 2000 Hz
/// Parameterless constructor
public FlowMeterCfg()
{
}
/// <summary>
/// Flow meter configuration parameters
/// </summary>
/// <param name="name">Flow meter name</param>
/// <param name="position">Position on the control board 1..5</param>
public FlowMeterCfg(IComponentFactory factory, string name, string parentName, int position, float nominalFlow)
: base(factory, name, parentName)
{
if (position < 1 || position > 5) throw new ArgumentOutOfRangeException("position");
this.Position = position;
this.NominalFlow = nominalFlow;
}
public IComponentCfg Clone()
{
return new FlowMeterCfg(Factory, Name, ParentName, Position, NominalFlow);
}
public string ToString(int i)
{
return string.Format("position={0}, nominalFlow={1}", Position, NominalFlow);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
FlowMeterCfg config = (FlowMeterCfg)(new XmlSerializer(typeof(FlowMeterCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,153 @@
namespace TBF.BenchControl.Elde.FlowMeter
{
partial class FlowMeterCfgCtrl
{
/// <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.positionTextBox = new System.Windows.Forms.TextBox();
this.positionLabel = new System.Windows.Forms.Label();
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.nominalFlowTextBox = new System.Windows.Forms.TextBox();
this.nominalFlowLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// positionTextBox
//
this.positionTextBox.Enabled = false;
this.positionTextBox.Location = new System.Drawing.Point(224, 113);
this.positionTextBox.Name = "positionTextBox";
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
this.positionTextBox.TabIndex = 6;
//
// positionLabel
//
this.positionLabel.AutoSize = true;
this.positionLabel.Location = new System.Drawing.Point(30, 116);
this.positionLabel.Name = "positionLabel";
this.positionLabel.Size = new System.Drawing.Size(44, 13);
this.positionLabel.TabIndex = 5;
this.positionLabel.Text = "Position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(30, 90);
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(140, 61);
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, 64);
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(137, 37);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// nominalFlowTextBox
//
this.nominalFlowTextBox.Enabled = false;
this.nominalFlowTextBox.Location = new System.Drawing.Point(224, 138);
this.nominalFlowTextBox.Name = "nominalFlowTextBox";
this.nominalFlowTextBox.Size = new System.Drawing.Size(46, 20);
this.nominalFlowTextBox.TabIndex = 8;
//
// nominalFlowLabel
//
this.nominalFlowLabel.AutoSize = true;
this.nominalFlowLabel.Location = new System.Drawing.Point(30, 141);
this.nominalFlowLabel.Name = "nominalFlowLabel";
this.nominalFlowLabel.Size = new System.Drawing.Size(140, 13);
this.nominalFlowLabel.TabIndex = 7;
this.nominalFlowLabel.Text = "Nominal flow [m3/h @2kHz]";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(140, 87);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// FlowMeterCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.nominalFlowTextBox);
this.Controls.Add(this.nominalFlowLabel);
this.Controls.Add(this.positionTextBox);
this.Controls.Add(this.positionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "FlowMeterCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.FlowMeterCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox positionTextBox;
private System.Windows.Forms.Label positionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.TextBox nominalFlowTextBox;
private System.Windows.Forms.Label nominalFlowLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,102 @@
using System;
using System.Globalization;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.FlowMeter
{
public partial class FlowMeterCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(FlowMeterCfgCtrl));
ComponentParametersDlg parent;
FlowMeterCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as FlowMeterCfg;
Redraw();
}
}
public FlowMeterCfgCtrl()
{
InitializeComponent();
}
private void FlowMeterCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
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;
positionTextBox.Text = config.Position.ToString();
nominalFlowTextBox.Text = config.NominalFlow.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
positionTextBox.Enabled = true;
nominalFlowTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 1 || dummy > 5)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Position' should be between 1 and 5";
}
float fdummy;
if (!Utils.TryParseUFloat(nominalFlowTextBox.Text, out fdummy) || fdummy < 0.2 || fdummy > 1000)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Nominal flow' should be between 0.2 and 1000";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.Position = int.Parse(positionTextBox.Text);
Utils.TryParseUFloat(nominalFlowTextBox.Text, out config.NominalFlow);
}
}
}
@@ -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>
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.FlowMeter
{
public class FlowMeterFactory : IComponentFactory
{
public string ClassName { get { return "FlowMeter"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 5; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new FlowMeterCfg(this, "FlowMeter", "CB", 1, 1);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new FlowMeterCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new FlowMeter((FlowMeterCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return FlowMeterCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { FlowMeter.ResetStaticProperties(); }
}
}
@@ -0,0 +1,65 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde.FlowMeter
{
public class ReadFlowOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
public override string ToString() { return string.Format("ReadFlowOp(.,{0},{1},.)", eventDone, flowMeterNr); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly int flowMeterNr;
readonly Event eventDone;
FloatBox flow;
/// <summary>
/// Events: FlowInDone, FlowOutDone or Error
/// </summary>
/// <param name="flowMeter">Flow meter reference</param>
/// <param name="flow">Reference to the measured flow variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadFlowOp(FlowMeter flowMeter, ref FloatBox flow, Event eventDone)
{
if (flowMeter == null) throw new ArgumentNullException("flowMeter");
this.controlBoard = flowMeter.ControlBoard;
this.flowMeterNr = flowMeter.Position;
this.eventDone = eventDone;
this.flow = flow;
log.Debug(this.ToString());
}
public ReadFlowOp(FlowMeter flowMeter, ref FloatBox flow)
: this(flowMeter, ref flow, Event.FlowMeasurementDone)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (flowMeterNr == (int)(controlBoard.StatusP & StatusP.RefFlowMeterMask))
{
flow.F = controlBoard.ReferenceFlow;
return eventDone;
}
else
{
return Event.Error;
}
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,69 @@
namespace TBF.BenchControl.Elde
{
interface IControlCom
{
StatusP StatusP { get; }
float ReferenceFreq { get; }
int EtPulses(int wmNr0);
int WMeterPulses(int wmNr0);
int WMeterReference(int wmNr0);
uint RegulValveDAC { get; }
float Pressure(int prsNr0);
float Temperature(int tmpNr0);
RegulValveState RegulValveState(int rvNr1);
ulong RRoute { get; }
uint DivTime { get; }
float TTime { get; }
uint FmState { get; }
uint BeginState(int wmNr0);
float ReferenceFlow { get; }
float RValvePosition(int rvNr1);
float DivSamples(int ms);
int ScopeSamples(int i, int j, int k);
uint DigitalInputs { get; }
float AnalogInput(int adcNr0);
uint AnalogInputRaw(int adcNr0, int bank);
float ReferenceVolume { get; }
float VyslExt(int wmNr0, int what);
void SetWeight(int pos, float mass);
/// <summary>
/// Sends calibration and configuration data to the control board.
/// </summary>
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
/// <param name="etCalib">Etalon nominal values</param>
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib, float[] etCalib, uint[] divEdge, uint[] balanceRange);
/// <summary>
/// Updates a command that is regularly sent to the control board by SendCommand.
/// </summary>
/// <param name="cmd">See ControlBoard.Command enum</param>
/// <param name="refNr">Number of the etalon/reference (1..5)</param>
/// <param name="route">Route: 64-bit installation specific number</param>
/// <param name="refPulses">kolko impulzov ma trvat skuska</param>
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
/// <param name="filterConstant">0 = No filtering (0..255)</param>
/// <param name="FMFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
/// <param name="regConst">Coefficient used to control reg. valves (1..100)</param>
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
/// <param name="stopDevs">What to stop</param>
void SendCommand(Command cmd, int refNr, ulong route, int refPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs);
/// <summary>
/// Control of regulating valves.
/// </summary>
/// <param name="valveNo">Regulating valve nr. (1..5)</param>
/// <param name="valveMode">???</param>
/// <param name="valveValue">???</param>
void ValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue);
void RunDeviceBefore();
void RunDeviceAfter();
}
}
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PressureMeter
{
public class PressureMeter : IComponent, GenericDevices.IPressureMeter
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(PressureMeter));
public override string ToString()
{
return string.Format("PressureMeter({0},{1})", Name, Index);
}
public static void ResetStaticProperties() { }
readonly PressureMeterCfg pressureMeterCfg;
public Generic.IComponentCfg Cfg { get { return pressureMeterCfg; } }
public string Name { get { return pressureMeterCfg.Name; } }
public IList<Entities.MeasurementCorrection> Corrections { get { return pressureMeterCfg.Corrections; } }
public readonly ControlBoardDev ControlBoard;
public readonly int Index; /// 0..3
public readonly byte RS485Address; /// 0..255
public PressureMeter(PressureMeterCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.pressureMeterCfg = cfg;
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
Index = cfg.Position;
RS485Address = cfg.RS485Address;
/// Prepare data for SendCalibData() control board component method
ControlBoard.MeretRS485Address[Index] = RS485Address;
log.Debug(this.ToString());
}
/// <summary>
/// Events: PressureDone, Error
/// </summary>
/// <param name="pressure">Reference to a variable for the pressure in Bar</param>
/// <returns>ReadPressureOp instance reference casted to IOperaton</returns>
public IOperation ReadPressureOp(ref FloatBox pressure)
{
return new ReadPressureOp(this, ref pressure);
}
/// <summary>
/// Events: pressureDone, Error
/// </summary>
/// <param name="pressure">Reference to a variable for the pressure in Bar</param>
/// <param name="pressureDone">Event returned when measurement done</param>
/// <returns>ReadPressureOp instance reference casted to IOperaton</returns>
public IOperation ReadPressureOp(ref FloatBox pressure, Event pressureDone)
{
return new ReadPressureOp(this, ref pressure, pressureDone);
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PressureMeter
{
public class PressureMeterCfg : ComponentCfgBase, Generic.IChildComponentCfg
{
public int Position; /// 0..7
public byte RS485Address; /// 0..255
/// Parameterless constructor
public PressureMeterCfg()
{
}
/// <summary>
/// Regulation valve configuration parameters
/// </summary>
/// <param name="name">Regulation valve name</param>
/// <param name="index">Position on the control board 1..5</param>
/// <param name="dacValueClosed">0..1023</param>
/// <param name="dacValueOpen">0..1023</param>
public PressureMeterCfg(IComponentFactory factory, string name, string parentName, int index, byte rs485Address)
: base(factory, name, parentName)
{
if (index < 0 || index > 7) throw new ArgumentOutOfRangeException("Position");
this.Position = index;
if (rs485Address < 0 || rs485Address > 255) throw new ArgumentOutOfRangeException("RS485Address");
this.RS485Address = rs485Address;
}
public IComponentCfg Clone()
{
return new PressureMeterCfg(Factory, Name, ParentName, Position, RS485Address);
}
public string ToString(int i)
{
return string.Format("index={0}, RS485 address={1}", Position, RS485Address);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
PressureMeterCfg config = (PressureMeterCfg)(new XmlSerializer(typeof(PressureMeterCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,153 @@
namespace TBF.BenchControl.Elde.PressureMeter
{
partial class PressureMeterCfgCtrl
{
/// <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.positionTextBox = new System.Windows.Forms.TextBox();
this.positionLabel = new System.Windows.Forms.Label();
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.componentNameLabel = new System.Windows.Forms.Label();
this.rs485AddressLabel = new System.Windows.Forms.Label();
this.rs485AddressTextBox = new System.Windows.Forms.TextBox();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// positionTextBox
//
this.positionTextBox.Enabled = false;
this.positionTextBox.Location = new System.Drawing.Point(138, 104);
this.positionTextBox.Name = "positionTextBox";
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
this.positionTextBox.TabIndex = 6;
//
// positionLabel
//
this.positionLabel.AutoSize = true;
this.positionLabel.Location = new System.Drawing.Point(28, 107);
this.positionLabel.Name = "positionLabel";
this.positionLabel.Size = new System.Drawing.Size(44, 13);
this.positionLabel.TabIndex = 5;
this.positionLabel.Text = "Position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(28, 81);
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(138, 52);
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(28, 55);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// componentNameLabel
//
this.componentNameLabel.AutoSize = true;
this.componentNameLabel.Location = new System.Drawing.Point(135, 28);
this.componentNameLabel.Name = "componentNameLabel";
this.componentNameLabel.Size = new System.Drawing.Size(83, 13);
this.componentNameLabel.TabIndex = 0;
this.componentNameLabel.Text = "ComonentName";
//
// rs485AddressLabel
//
this.rs485AddressLabel.AutoSize = true;
this.rs485AddressLabel.Location = new System.Drawing.Point(28, 133);
this.rs485AddressLabel.Name = "rs485AddressLabel";
this.rs485AddressLabel.Size = new System.Drawing.Size(81, 13);
this.rs485AddressLabel.TabIndex = 7;
this.rs485AddressLabel.Text = "RS485 Address";
//
// rs485AddressTextBox
//
this.rs485AddressTextBox.Enabled = false;
this.rs485AddressTextBox.Location = new System.Drawing.Point(138, 130);
this.rs485AddressTextBox.Name = "rs485AddressTextBox";
this.rs485AddressTextBox.Size = new System.Drawing.Size(46, 20);
this.rs485AddressTextBox.TabIndex = 8;
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(138, 78);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// PressureMeterCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.rs485AddressTextBox);
this.Controls.Add(this.rs485AddressLabel);
this.Controls.Add(this.positionTextBox);
this.Controls.Add(this.positionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.componentNameLabel);
this.Name = "PressureMeterCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.PressureMeterCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox positionTextBox;
private System.Windows.Forms.Label positionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label componentNameLabel;
private System.Windows.Forms.Label rs485AddressLabel;
private System.Windows.Forms.TextBox rs485AddressTextBox;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,100 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PressureMeter
{
public partial class PressureMeterCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(PressureMeterCfgCtrl));
ComponentParametersDlg parent;
PressureMeterCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as PressureMeterCfg;
Redraw();
}
}
public PressureMeterCfgCtrl()
{
InitializeComponent();
}
private void PressureMeterCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
componentNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
positionTextBox.Text = config.Position.ToString();
rs485AddressTextBox.Text = config.RS485Address.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
positionTextBox.Enabled = true;
rs485AddressTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 0 || dummy > 7)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Position' should be between 0 and 7";
}
if (!int.TryParse(rs485AddressTextBox.Text, out dummy) || dummy < 0 || dummy > 255)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'RS485 Address' should be between 0 and 255";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.Position = int.Parse(positionTextBox.Text);
config.RS485Address = (byte)int.Parse(rs485AddressTextBox.Text);
}
}
}
@@ -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>
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PressureMeter
{
public class PressureMeterFactory : IComponentFactory
{
public string ClassName { get { return "PressureMeter"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 5; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new PressureMeterCfg(this, "PressureMeter", "CB", 1, 99);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new PressureMeterCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new PressureMeter((PressureMeterCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return PressureMeterCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { PressureMeter.ResetStaticProperties(); }
}
}
@@ -0,0 +1,58 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde.PressureMeter
{
public class ReadPressureOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadPressureOp));
public override string ToString() { return string.Format("ReadPressureOp(.,{0},{1},.)", eventDone, pressureMeterNr); }
/// Set by the constructor
readonly ControlBoardDev controlBoardDev;
readonly int pressureMeterNr;
readonly Event eventDone;
FloatBox pressure;
/// <summary>
/// Events: PressureInDone, PressureOutDone or Error
/// </summary>
/// <param name="pressureMeter">Pressure meter reference</param>
/// <param name="pressure">Reference to the measured pressure variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadPressureOp(PressureMeter pressureMeter, ref FloatBox pressure, Event eventDone)
{
if (pressureMeter == null) throw new ArgumentNullException("pressureMeter");
this.controlBoardDev = pressureMeter.ControlBoard;
this.pressureMeterNr = pressureMeter.Index;
this.eventDone = eventDone;
this.pressure = pressure;
log.Debug(this.ToString());
}
public ReadPressureOp(PressureMeter pressureMeter, ref FloatBox pressure)
: this(pressureMeter, ref pressure, Event.PressureDone)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.PressureInDone or Event.PressureOutDone
/// </returns>
public Event Run()
{
pressure.F = controlBoardDev.Pressure(pressureMeterNr);
return eventDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using log4net;
namespace TBF.BenchControl.Elde.Pump
{
public class Pump : Generic.IComponent, GenericDevices.IPump, GenericDevices.IValve
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(Pump));
public override string ToString()
{
return string.Format("Pump(name={0}, bit={1})", Name, bitPosition);
}
public static void ResetStaticProperties() { }
private readonly PumpCfg pumpCfg;
public Generic.IComponentCfg Cfg { get { return pumpCfg; } }
public string Name { get { return pumpCfg.Name; } }
public GenericDevices.IValve CoupledTo { get { return null; } }
public bool Invert { get { return false; } }
public int LagOpening { get { return 0; } }
public int LagClosing { get { return 0; } }
readonly ControlBoardDev controlBoard;
readonly int bitPosition; /// 0 .. 63
public readonly ulong Mask; /// derived from bitPosition in the constructor
public Pump(PumpCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.pumpCfg = cfg;
controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
this.bitPosition = cfg.BitPosition;
this.Mask = (((ulong)1) << bitPosition);
log.Debug(this.ToString());
}
public bool State
{
get { return (controlBoard.Route & Mask) != 0; }
}
}
}
@@ -0,0 +1,52 @@
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Pump
{
public class PumpCfg : ComponentCfgBase, IChildComponentCfg
{
public int BitPosition;
/// Parameterless constructor
public PumpCfg()
{
}
/// Constructor
public PumpCfg(IComponentFactory factory, string name, string parentName, int bitPosition)
: base(factory, name, parentName)
{
this.BitPosition = bitPosition;
}
public IComponentCfg Clone()
{
return new PumpCfg(Factory, Name, ParentName, BitPosition);
}
public string ToString(int i)
{
return string.Format("bit={0}", BitPosition);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
PumpCfg config = (PumpCfg)(new XmlSerializer(typeof(PumpCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,130 @@
namespace TBF.BenchControl.Elde.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.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;
//
// PumpCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
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;
}
}
@@ -0,0 +1,92 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Pump
{
public partial class PumpCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(PumpCfgCtrl));
ComponentParametersDlg parent;
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.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
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.BitPosition.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
bitPositionTextBox.Enabled = true;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.BitPosition = int.Parse(bitPositionTextBox.Text);
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 64)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 63";
}
return flags;
}
}
}
@@ -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>
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Pump
{
public class PumpFactory : IComponentFactory
{
public string ClassName { get { return "Pump"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return int.MaxValue; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new PumpCfg(this, "Pump", "CB", 0);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new PumpCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new Pump((PumpCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return PumpCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { Pump.ResetStaticProperties(); }
}
}
@@ -0,0 +1,151 @@
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
using TBF.Resources;
namespace TBF.BenchControl.Elde.PumpWithFM
{
public class FMPumpTestParams : IParamsProvider, ITestParams
{
public float Power; /// Target=terminal flow durning detection when increasing or decreasing the flow
string[] paramNames = new string[]
{
Strings.PowerPct,
};
public string ParamName(int i) { return paramNames[i]; }
public string ToString(int i)
{
switch (i)
{
case 0: return Power.ToString("F1");
default: return string.Empty;
}
}
public void UpdateParam(int i, string strValue)
{
switch (i)
{
case 0: Power = Utils.ParseUFloat(strValue); return;
default: return;
}
}
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
float dummy;
switch (i)
{
case 0:
if (Utils.TryParseUFloat(strValue, out dummy)) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
#region Boilerplate code
public int ParamsCount() { return paramNames.Length; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ParamsCount(); i++)
{
if (i != 0) sb.Append("; ");
sb.Append(ParamName(i));
sb.Append("=");
sb.Append(ToString(i));
}
return sb.ToString();
}
[XmlIgnore]
public Entities.ComponentTest TestParamsEntity { get { return testParamsEntity; } }
Entities.ComponentTest testParamsEntity;
[XmlIgnore]
public string ComponentName { get { return componentName; } }
string componentName;
[XmlIgnore]
public Entities.Test Test { get { return test; } }
Entities.Test test;
/// Parameterless constructor
public FMPumpTestParams()
{
Power = 50.0f;
}
public FMPumpTestParams(Entities.ComponentTest testParamsEntity, string componentName, Entities.Test test)
: this()
{
this.testParamsEntity = testParamsEntity;
this.componentName = componentName;
this.test = test;
}
public TBF.Entities.ComponentTest ToDbEntity(IComponent component, Entities.Test test)
{
using (var writer = new StringWriter())
{
/// Serialize this class with parameters
(new XmlSerializer(GetType())).Serialize(writer, this);
/// Create and return the ComponentTest entity
TBF.Entities.ComponentTest entity = new TBF.Entities.ComponentTest();
entity.CmpntName = component.Cfg.Name;
entity.Parameters = writer.ToString();
entity.Test = test;
return entity;
}
}
public void UpdateDbEntity()
{
using (var writer = new StringWriter())
{
/// Serialize this class and update the entity
(new XmlSerializer(GetType())).Serialize(writer, this);
testParamsEntity.Parameters = writer.ToString();
testParamsEntity.CmpntName = componentName;
testParamsEntity.Test = test;
}
}
public static IParamsProvider GetTestParams(Entities.ComponentTest testParamsEntity)
{
if (testParamsEntity == null) return new FMPumpTestParams();
FMPumpTestParams testParams;
try
{
testParams = (FMPumpTestParams)(new XmlSerializer(typeof(FMPumpTestParams)))
.Deserialize(new StringReader(testParamsEntity.Parameters));
}
catch
{
testParams = new FMPumpTestParams();
}
testParams.testParamsEntity = testParamsEntity;
testParams.componentName = testParamsEntity.CmpntName;
testParams.test = testParamsEntity.Test;
return testParams;
}
#endregion
}
}
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using log4net;
namespace TBF.BenchControl.Elde.PumpWithFM
{
public class Pump : Generic.IComponent, GenericDevices.IPumpFM, GenericDevices.IValve, IOperation
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(Pump));
public override string ToString()
{
return string.Format("Pump(name={0}, bit={1}, idx={2})", Name, bitPosition, FMIndex);
}
public static void ResetStaticProperties() { }
private readonly PumpCfg pumpCfg;
public Generic.IComponentCfg Cfg { get { return pumpCfg; } }
public string Name { get { return pumpCfg.Name; } }
public GenericDevices.IValve CoupledTo { get { return null; } }
public bool Invert { get { return false; } }
public int LagOpening { get { return 0; } }
public int LagClosing { get { return 0; } }
readonly ControlBoardDev controlBoard;
readonly int bitPosition; /// 0 .. 63
int FMIndex; /// 0 .. FMPumpsCount-1
public readonly ulong Mask; /// derived from bitPosition in the constructor
public bool State
{
get { return (controlBoard.Route & Mask) != 0; }
}
public Pump(PumpCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.pumpCfg = cfg;
controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
this.bitPosition = cfg.BitPosition;
this.Mask = (((ulong)1) << bitPosition);
this.FMIndex = cfg.FMIndex;
log.Debug(this.ToString());
}
/// <summary>
/// The currently running operation.
/// </summary>
public enum CurrentOp
{
None,
TurnOn,
TurnOff,
}
///
CurrentOp currentOp;
/// <summary>
/// Turn the pump frequency inverter on.
/// </summary>
public IOperation TurnOn()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.TurnOn;
return this;
}
/// <summary>
/// Turn the pump frequency inverter on.
/// </summary>
public IOperation TurnOff()
{
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:
controlBoard.SetFMFreq(FMIndex, 50.0f);
return;
case CurrentOp.TurnOff:
default:
controlBoard.SetFMFreq(FMIndex, 0.0f);
return;
}
}
/// <summary>Run the operation</summary>
public Event Run()
{
return Event.TurnPumpOnOffDone;
}
/// <summary>Stop the operation</summary>
public void Stop()
{
currentOp = CurrentOp.None;
}
}
}
@@ -0,0 +1,53 @@
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PumpWithFM
{
public class PumpCfg : ComponentCfgBase, IChildComponentCfg
{
public int BitPosition;
public int FMIndex;
/// Parameterless constructor
public PumpCfg()
{
}
/// Constructor
public PumpCfg(IComponentFactory factory, string name, string parentName, int bitPosition, int fmIndex)
: base(factory, name, parentName)
{
this.BitPosition = bitPosition;
this.FMIndex = fmIndex;
}
public IComponentCfg Clone()
{
return new PumpCfg(Factory, Name, ParentName, BitPosition, FMIndex);
}
public string ToString(int i)
{
return string.Format("bit={0}, fmIdx={1}", BitPosition, FMIndex);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
PumpCfg config = (PumpCfg)(new XmlSerializer(typeof(PumpCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,153 @@
namespace TBF.BenchControl.Elde.PumpWithFM
{
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.fmIndexTextBox = new System.Windows.Forms.TextBox();
this.fmIndexLabel = 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;
//
// fmIndexTextBox
//
this.fmIndexTextBox.Enabled = false;
this.fmIndexTextBox.Location = new System.Drawing.Point(122, 124);
this.fmIndexTextBox.Name = "fmIndexTextBox";
this.fmIndexTextBox.Size = new System.Drawing.Size(46, 20);
this.fmIndexTextBox.TabIndex = 8;
//
// fmIndexLabel
//
this.fmIndexLabel.AutoSize = true;
this.fmIndexLabel.Location = new System.Drawing.Point(36, 127);
this.fmIndexLabel.Name = "fmIndexLabel";
this.fmIndexLabel.Size = new System.Drawing.Size(51, 13);
this.fmIndexLabel.TabIndex = 7;
this.fmIndexLabel.Text = "FM Index";
//
// PumpCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.fmIndexTextBox);
this.Controls.Add(this.fmIndexLabel);
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 fmIndexTextBox;
private System.Windows.Forms.Label fmIndexLabel;
}
}
@@ -0,0 +1,100 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PumpWithFM
{
public partial class PumpCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(PumpCfgCtrl));
ComponentParametersDlg parent;
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.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
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.BitPosition.ToString();
fmIndexTextBox.Text = config.FMIndex.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
bitPositionTextBox.Enabled = true;
fmIndexTextBox.Enabled = true;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.BitPosition = int.Parse(bitPositionTextBox.Text);
config.FMIndex = int.Parse(fmIndexTextBox.Text);
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 64)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 63";
}
if (!int.TryParse(fmIndexTextBox.Text, out dummy) || dummy < 0)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'FM Index' should be between 0 and FMPumpsCount - 1";
}
return flags;
}
}
}
@@ -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>
@@ -0,0 +1,42 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.PumpWithFM
{
public class PumpFactory : IComponentFactory
{
public string ClassName { get { return "PumpWithFM"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return true; } }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams)
{
return FMPumpTestParams.GetTestParams(testParams);
}
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return int.MaxValue; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new PumpCfg(this, "Pump", "CB", 0, 0);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new PumpCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new Pump((PumpCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return PumpCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { Pump.ResetStaticProperties(); }
}
}
@@ -0,0 +1,59 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class QueryMeasurementEndOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(QueryMeasurementEndOp));
public override string ToString() { return string.Format("QueryMeasurementEndOp(.,{0})", eventDone); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly Event eventDone;
bool done = false;
/// <summary>
/// Events: MeasurementCompleted
/// </summary>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public QueryMeasurementEndOp(ControlBoardDev controlBoardDev, Event eventDone)
{
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
this.controlBoard = controlBoardDev;
this.eventDone = eventDone;
log.Debug(this.ToString());
}
public QueryMeasurementEndOp(ControlBoardDev controlBoardDev)
: this(controlBoardDev, Event.MeasurementCompleted)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (done) return eventDone;
if (0 != (controlBoard.StatusP & StatusP.TestCompleted))
{
done = true;
return eventDone;
}
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,155 @@
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
using TBF.Resources;
namespace TBF.BenchControl.Elde.RegisterReader
{
public class RRProcedureParams : IParamsProvider, IProcedureParams
{
public float PulsesPerLtr; /// Target low limit of the flow increase or decrease
string[] paramNames = new string[]
{
Strings.PulsesPerLtr,
};
public string ParamName(int i) { return paramNames[i]; }
public string ToString(int i)
{
switch (i)
{
case 0: return PulsesPerLtr.ToString();
default: return string.Empty;
}
}
/// <summary>
/// Parameterless constructor - sets default values of parameters.
/// </summary>
public RRProcedureParams()
{
PulsesPerLtr = 1.0f;
}
/// Retrieves parameters from UI controls
public void UpdateParam(int i, string strValue)
{
switch (i)
{
case 0: PulsesPerLtr = Utils.ParseUFloat(strValue); return;
default: return;
}
}
/// Verifies whether strings in UI controls represent valid parameters
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
float dummy;
switch (i)
{
case 0:
if (Utils.TryParseUFloat(strValue, out dummy)) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
#region Boilerplate code
public int ParamsCount() { return paramNames.Length; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ParamsCount(); i++)
{
if (i != 0) sb.Append("; ");
sb.Append(ParamName(i));
sb.Append("=");
sb.Append(ToString(i));
}
return sb.ToString();
}
[XmlIgnore]
public Entities.ComponentProcedure ProcedureParamsEntity { get { return procedureParamsEntity; } }
Entities.ComponentProcedure procedureParamsEntity;
[XmlIgnore]
public string ComponentName { get { return componentName; } }
string componentName;
[XmlIgnore]
public Entities.Procedure Procedure { get { return procedure; } }
Entities.Procedure procedure;
public RRProcedureParams(Entities.ComponentProcedure procedureParamsEntity, string componentName, Entities.Procedure procedure)
: this()
{
this.procedureParamsEntity = procedureParamsEntity;
this.componentName = componentName;
this.procedure = procedure;
}
public TBF.Entities.ComponentProcedure ToDbEntity(IComponent component, Entities.Procedure procedure)
{
using (var writer = new StringWriter())
{
/// Serialize this class with parameters
(new XmlSerializer(GetType())).Serialize(writer, this);
/// Create and return the ComponentProcedure entity
TBF.Entities.ComponentProcedure entity = new TBF.Entities.ComponentProcedure();
entity.CmpntName = component.Cfg.Name;
entity.Parameters = writer.ToString();
entity.Procedure = procedure;
return entity;
}
}
public void UpdateDbEntity()
{
using (var writer = new StringWriter())
{
/// Serialize this class and update the entity
(new XmlSerializer(GetType())).Serialize(writer, this);
procedureParamsEntity.Parameters = writer.ToString();
procedureParamsEntity.CmpntName = componentName;
procedureParamsEntity.Procedure = procedure;
}
}
public static IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParamsEntity)
{
if (procedureParamsEntity == null) return new RRProcedureParams();
RRProcedureParams procedureParams;
try
{
procedureParams = (RRProcedureParams)(new XmlSerializer(typeof(RRProcedureParams)))
.Deserialize(new StringReader(procedureParamsEntity.Parameters));
}
catch
{
procedureParams = new RRProcedureParams();
}
procedureParams.procedureParamsEntity = procedureParamsEntity;
procedureParams.componentName = procedureParamsEntity.CmpntName;
procedureParams.procedure = procedureParamsEntity.Procedure;
return procedureParams;
}
#endregion
}
}
@@ -0,0 +1,58 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde.RegisterReader
{
public class ReadReferenceForRegisterOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadReferenceForRegisterOp));
public override string ToString() { return string.Format("ReadWaterMeterOp(.,{0},{1},.)", eventDone, registerNr); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly int registerNr; /// 0 .. nr.watermeters-1
readonly Event eventDone;
IntBox pulses;
/// <summary>
/// Events: or Error
/// </summary>
/// <param name="register">Flow meter reference</param>
/// <param name="flow">Reference to the measured flow variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadReferenceForRegisterOp(Elde.RegisterReader.RegisterReader register, ref IntBox pulses, Event eventDone)
{
if (register == null) throw new ArgumentNullException("register");
this.controlBoard = register.ControlBoard;
this.registerNr = register.Position;
this.eventDone = eventDone;
this.pulses = pulses;
log.Debug(this.ToString());
}
public ReadReferenceForRegisterOp(Elde.RegisterReader.RegisterReader register, ref IntBox pulses)
: this(register, ref pulses, Event.ReadReferenceDone)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
pulses.N = (int)controlBoard.EtPulses(registerNr);
return eventDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,71 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde.RegisterReader
{
public class ReadRegisterOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadRegisterOp));
public override string ToString() { return string.Format("ReadRegisterOp({0})", reader.Name); }
/// Set by the constructor
readonly RegisterReader reader;
IntBox pulses;
IntBox refPulses;
/// <summary>
/// Events: Event.ReadRegisterDone or Event.Error
/// </summary>
/// <param name="reader">Register reader reference</param>
/// <param name="pulses">Reference to a field with the water meter pulses</param>
public ReadRegisterOp(GenericDevices.IRegisterReader reader, ref IntBox pulses)
{
this.reader = reader as RegisterReader;
if (reader == null) throw new ArgumentNullException("reader is null or it is not Elde");
this.pulses = pulses;
log.Debug(this.ToString());
}
/// <summary>
/// Events: Event.ReadRegisterDone or Event.Error
/// </summary>
/// <param name="reader">Register reader reference</param>
/// <param name="pulses">Reference to a Box with the water meter pulses</param>
/// <param name="refPulses">Reference to a Box with the reference flow meter pulses synchronized with the water meter</param>
public ReadRegisterOp(GenericDevices.IRegisterReader reader, ref IntBox pulses, ref IntBox refPulses)
: this(reader, ref pulses)
{
this.refPulses = refPulses;
log.Debug(this.ToString());
}
private void ReadPulses()
{
pulses.N = (int)reader.ControlBoard.WMeterPulses(reader.Position);
if (refPulses != null)
{
refPulses.N = (int)reader.ControlBoard.EtPulses(reader.Position);
}
}
/// <summary>Start this operation</summary>
public void Start()
{
ReadPulses();
}
/// <summary>Run this operation</summary>
/// <returns>eventDone</returns>
public Event Run()
{
ReadPulses();
return Event.ReadRegisterDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using log4net;
namespace TBF.BenchControl.Elde.RegisterReader
{
public class RegisterReader : ComponentBase, GenericDevices.IRegisterReader
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(RegisterReader));
public override string ToString()
{
return string.Format("Register({0},{1})", Name, Position);
}
public static void ResetStaticProperties() { }
RegisterReaderCfg registerReaderCfg;
public float PulsesPerLtr
{
get
{
return (ProcedureParams is RRProcedureParams) ? (ProcedureParams as RRProcedureParams).PulsesPerLtr : 0;
}
}
public readonly ControlBoardDev ControlBoard;
public readonly int Position; /// 1 .. inf
public RegisterReader(RegisterReaderCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.registerReaderCfg = cfg;
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
Position = cfg.Position;
/// Prepare data for SendCalibData() control board component method
log.Debug(this.ToString());
}
/// <summary>
/// Events: Event.ReadRegisterDone, Event.Error
/// </summary>
/// <param name="pulses">Reference to a variable for the water meter pulses</param>
/// <returns>ReadWaterMeter instance reference casted to IOperaton</returns>
public IOperation ReadRegisterOp(ref IntBox pulses)
{
return new ReadRegisterOp(this, ref pulses);
}
/// <summary>
/// Events: Event.ReadRegisterDone, Event.Error
/// </summary>
/// <param name="pulses">Reference to a variable for the water meter pulses</param>
/// <param name="pulses">Reference to a variable for the related reference flowmeter pulses</param>
/// <returns>Reference to operation object instance</returns>
public IOperation ReadRegisterOp(ref IntBox pulses, ref IntBox refPulses)
{
return new ReadRegisterOp(this, ref pulses, ref refPulses);
}
/// <summary>
/// Events: ReadReferenceDone, Error
/// </summary>
/// <param name="pulses">Reference to a variable for the water meter pulses</param>
/// <returns>Reference to operation object instance</returns>
public IOperation ReadReferenceForRegisterOp(ref IntBox pulses, ref IntBox refPulses)
{
return new ReadReferenceForRegisterOp(this, ref pulses);
}
}
}
@@ -0,0 +1,60 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegisterReader
{
public class RegisterReaderCfg : ComponentCfgBase, Generic.IChildComponentCfg
{
public int Position; /// 1..nrWaterMeters
/// Parameterless constructor
public RegisterReaderCfg()
{
}
/// <summary>
/// Regulation valve configuration parameters
/// </summary>
/// <param name="name">Regulation valve name</param>
/// <param name="position">Position on the control board 1 .. nrWaterMeters</param>
public RegisterReaderCfg(IComponentFactory factory, string name, string parentName, int position)
: base(factory, name, parentName)
{
if (position < 1 || position >= 2 * Program.WMsCount)
{
throw new ArgumentOutOfRangeException("position");
}
this.Position = position;
}
public IComponentCfg Clone()
{
return new RegisterReaderCfg(Factory, Name, ParentName, Position);
}
public string ToString(int i)
{
return string.Format("position={0}", Position);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
RegisterReaderCfg config = (RegisterReaderCfg)(new XmlSerializer(typeof(RegisterReaderCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,130 @@
namespace TBF.BenchControl.Elde.RegisterReader
{
partial class RegisterReaderCfgCtrl
{
/// <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.positionTextBox = new System.Windows.Forms.TextBox();
this.positionLabel = new System.Windows.Forms.Label();
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.componentNameLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// positionTextBox
//
this.positionTextBox.Enabled = false;
this.positionTextBox.Location = new System.Drawing.Point(136, 119);
this.positionTextBox.Name = "positionTextBox";
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
this.positionTextBox.TabIndex = 6;
//
// positionLabel
//
this.positionLabel.AutoSize = true;
this.positionLabel.Location = new System.Drawing.Point(26, 122);
this.positionLabel.Name = "positionLabel";
this.positionLabel.Size = new System.Drawing.Size(44, 13);
this.positionLabel.TabIndex = 5;
this.positionLabel.Text = "Position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(26, 96);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent Name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(136, 67);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(26, 70);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// componentNameLabel
//
this.componentNameLabel.AutoSize = true;
this.componentNameLabel.Location = new System.Drawing.Point(133, 43);
this.componentNameLabel.Name = "componentNameLabel";
this.componentNameLabel.Size = new System.Drawing.Size(83, 13);
this.componentNameLabel.TabIndex = 0;
this.componentNameLabel.Text = "ComonentName";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(136, 93);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// RegisterReaderCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.positionTextBox);
this.Controls.Add(this.positionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.componentNameLabel);
this.Name = "RegisterReaderCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.RegisterReaderCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox positionTextBox;
private System.Windows.Forms.Label positionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label componentNameLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,92 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegisterReader
{
public partial class RegisterReaderCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(RegisterReaderCfgCtrl));
ComponentParametersDlg parent;
RegisterReaderCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as RegisterReaderCfg;
Redraw();
}
}
public RegisterReaderCfgCtrl()
{
InitializeComponent();
}
private void RegisterReaderCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
componentNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
positionTextBox.Text = config.Position.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
positionTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(positionTextBox.Text, out dummy) || (dummy < 1) || (dummy > 2 * Program.WMsCount))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Position' should be >= 1";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.Position = int.Parse(positionTextBox.Text);
}
}
}
@@ -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>
@@ -0,0 +1,46 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegisterReader
{
public class RegisterReaderFactory : IComponentFactory
{
public string ClassName { get { return "RegisterReader"; } }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return Program.WMsCount; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new RegisterReaderCfg(this, "Sick", "CB", 1);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new RegisterReaderCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new RegisterReader((RegisterReaderCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return RegisterReaderCfg.CreateFromDbEntity(component, this);
}
public bool HasProcedureParams { get { return true; } }
///
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams)
{
return RRProcedureParams.GetProcedureParams(procedureParams);
}
public bool HasTestParams { get { return false; } }
///
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public void ResetStaticProperties() { RegisterReader.ResetStaticProperties(); }
}
}
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.GenericDevices;
namespace TBF.BenchControl.Elde.RegulValve
{
public class ChangeRegulValvePositionOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ChangeRegulValvePositionOp));
public override string ToString()
{
return string.Format("ChangeRegulValvePositionOp({0},{1}s)", regulValve.Name, timePulseSec.ToString("F2"));
}
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly RegulValve regulValve;
readonly int regulValveNr;
readonly float timePulseSec;
/// Process values
bool firstRun;
/// <summary>
/// Set required water flow.
/// Events: FlowSet, FlowTimeOut
/// </summary>
/// <param name="controlBoard">Control board device</param>
/// <param name="regulValve">Regulation valve component</param>
/// <param name="posLoPct">Lower limit of the position to be achieved</param>
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
/// <param name="timeout">Timeout in sec. for setting the flow</param>
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
public ChangeRegulValvePositionOp(ControlBoardDev controlBoard, RegulValve regulValve, float timePulseSec)
{
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
this.controlBoard = controlBoard;
this.regulValve = regulValve as RegulValve;
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
this.regulValveNr = this.regulValve.Position;
this.timePulseSec = timePulseSec;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
firstRun = true;
float positionPct = controlBoard.RValvePosition(regulValveNr);
log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
controlBoard.ValveMove(regulValveNr,
RegulValveMode.PulseWidth,
new float[2] { timePulseSec, timePulseSec });
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.SetFlowDone
/// </returns>
public Event Run()
{
float positionPct = controlBoard.RValvePosition(regulValveNr);
log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
return Event.PositionReached;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegulValve
{
public class RegulValve : IComponent, GenericDevices.IRegulValve
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(RegulValve));
public override string ToString()
{
return string.Format("RegulationValve({0},{1})", Name, Position);
}
public static void ResetStaticProperties() { }
public RegulValveCfg RegulValveCfg;
public Generic.IComponentCfg Cfg { get { return RegulValveCfg; } }
public string Name { get { return Cfg.Name; } }
IDictionary<float, float> dict;
public IDictionary<float, float> Dict { get { return dict; } }
readonly ControlBoardDev controlBoard;
public readonly int Position; /// 0..7
public readonly int DacValueClosed; /// 0..1023
public readonly int DacValueOpen; /// 0..1023
public RegulValve(RegulValveCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.RegulValveCfg = cfg;
controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
this.Position = cfg.Position;
this.DacValueClosed = cfg.DacValueClosed;
this.DacValueOpen = cfg.DacValueOpen;
this.dict = new Dictionary<float, float>();
this.controlBoard.RegValveCalib[Position - 1, 0] = (uint)DacValueClosed;
this.controlBoard.RegValveCalib[Position - 1, 1] = (uint)DacValueOpen;
log.Debug(this.ToString());
}
/// <summary>
/// Operation to set the water flow within tolerances
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
/// </summary>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
/// <param name="measuredFlow">Measured flow [m3/h]</param>
/// <param name="timeout">Timeout in [s]</param>
/// <returns>SetFlowOp instance</returns>
public IOperation SetFlowOp(GenericDevices.IFlowMeter flowMeter, float requiredFlowLo, float requiredFlowHi, FloatBox measuredFlow, int timeout)
{
return new SetFlowOp(controlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout);
}
/// <summary>
/// Operation to set the water flow within tolerances. Leave the measurement running.
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
/// </summary>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
/// <param name="measuredFlow">Measured flow [m3/h]</param>
/// <param name="timeout">Timeout in [s]</param>
/// <returns>SetFlowOp instance</returns>
public IOperation SetFlowAndMeasureOp(GenericDevices.IFlowMeter flowMeter, float requiredFlowLo, float requiredFlowHi, FloatBox measuredFlow, int timeout)
{
return new SetFlowOp(controlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout, true);
}
/// <summary>
/// Operation to set the regulation valve to a required position
/// Events: Event.None
/// </summary>
/// <param name="flowLo">Lower limit of the required valve position in [%]</param>
/// <param name="flowLo">Higher limit of the required valve position in [%]</param>
/// <returns>SetPositionOp instance</returns>
public IOperation SetRegulValvePositionOp(float pctLo, float pctHi, int timeoutMs)
{
return new SetRegulValvePositionOp(controlBoard, this, pctLo, pctHi, timeoutMs);
}
public IOperation ChangeRegulValvePositionOp(float timePulseSec)
{
return new ChangeRegulValvePositionOp(controlBoard, this, timePulseSec);
}
}
}
@@ -0,0 +1,73 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegulValve
{
public class RegulValveCfg : ComponentCfgBase, IChildComponentCfg
{
public int Position; /// 0..7
public int DacValueClosed; /// 0..1023
public int DacValueOpen; /// 0..1023
public int PidCoef; /// 1..100
public bool StoredPositionReuse; /// true = store and re-use previous regulation valve positions
/// Parameterless constructor
public RegulValveCfg()
{
}
/// <summary>
/// Regulation valve configuration parameters
/// </summary>
/// <param name="name">Regulation valve name</param>
/// <param name="position">Position on the control board 0..7</param>
/// <param name="dacValueClosed">0..1023</param>
/// <param name="dacValueOpen">0..1023</param>
/// <param name="pidCoef">1..100</param>
public RegulValveCfg(IComponentFactory factory, string name, string parentName, int position, int dacValueClosed, int dacValueOpen, int pidCoef, bool storedPositionReuse)
: base(factory, name, parentName)
{
if (position < 0 || position > 7) throw new ArgumentOutOfRangeException("position");
if (dacValueClosed < 0 || dacValueClosed > 1023) throw new ArgumentOutOfRangeException("dacValueOpen");
if (dacValueOpen < 0 || dacValueOpen > 1023) throw new ArgumentOutOfRangeException("dacValueOpen");
if (pidCoef < 1 || pidCoef > 100) throw new ArgumentOutOfRangeException("pidCoef");
this.Position = position;
this.DacValueClosed = dacValueClosed;
this.DacValueOpen = dacValueOpen;
this.PidCoef = pidCoef;
this.StoredPositionReuse = storedPositionReuse;
}
public IComponentCfg Clone()
{
return new RegulValveCfg(Factory, Name, ParentName, Position, DacValueClosed, DacValueOpen, PidCoef, StoredPositionReuse);
}
public string ToString(int i)
{
return string.Format("position={0}, DAC-closed={1}, DAC-open={2}, PID={3}, posReuse={4}",
Position, DacValueClosed, DacValueOpen, PidCoef, StoredPositionReuse);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
RegulValveCfg config = (RegulValveCfg)(new XmlSerializer(typeof(RegulValveCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,213 @@
namespace TBF.BenchControl.Elde.RegulValve
{
partial class RegulValveCfgCtrl
{
/// <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.positionTextBox = new System.Windows.Forms.TextBox();
this.positionLabel = new System.Windows.Forms.Label();
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.dacClosedLabel = new System.Windows.Forms.Label();
this.dacClosedTextBox = new System.Windows.Forms.TextBox();
this.dacOpenTextBox = new System.Windows.Forms.TextBox();
this.dacOpenLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.pidCoefLabel = new System.Windows.Forms.Label();
this.pidCoefTextBox = new System.Windows.Forms.TextBox();
this.storedPosReuseCheckBox = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// positionTextBox
//
this.positionTextBox.Enabled = false;
this.positionTextBox.Location = new System.Drawing.Point(138, 78);
this.positionTextBox.Name = "positionTextBox";
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
this.positionTextBox.TabIndex = 6;
//
// positionLabel
//
this.positionLabel.AutoSize = true;
this.positionLabel.Location = new System.Drawing.Point(28, 81);
this.positionLabel.Name = "positionLabel";
this.positionLabel.Size = new System.Drawing.Size(18, 13);
this.positionLabel.TabIndex = 5;
this.positionLabel.Text = "ID";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(28, 57);
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(138, 30);
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(28, 33);
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(135, 9);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(89, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComponentName";
//
// dacClosedLabel
//
this.dacClosedLabel.AutoSize = true;
this.dacClosedLabel.Location = new System.Drawing.Point(28, 104);
this.dacClosedLabel.Name = "dacClosedLabel";
this.dacClosedLabel.Size = new System.Drawing.Size(93, 13);
this.dacClosedLabel.TabIndex = 7;
this.dacClosedLabel.Text = "DAC when Closed";
//
// dacClosedTextBox
//
this.dacClosedTextBox.Enabled = false;
this.dacClosedTextBox.Location = new System.Drawing.Point(138, 101);
this.dacClosedTextBox.Name = "dacClosedTextBox";
this.dacClosedTextBox.Size = new System.Drawing.Size(46, 20);
this.dacClosedTextBox.TabIndex = 8;
//
// dacOpenTextBox
//
this.dacOpenTextBox.Enabled = false;
this.dacOpenTextBox.Location = new System.Drawing.Point(138, 124);
this.dacOpenTextBox.Name = "dacOpenTextBox";
this.dacOpenTextBox.Size = new System.Drawing.Size(46, 20);
this.dacOpenTextBox.TabIndex = 10;
//
// dacOpenLabel
//
this.dacOpenLabel.AutoSize = true;
this.dacOpenLabel.Location = new System.Drawing.Point(28, 127);
this.dacOpenLabel.Name = "dacOpenLabel";
this.dacOpenLabel.Size = new System.Drawing.Size(87, 13);
this.dacOpenLabel.TabIndex = 9;
this.dacOpenLabel.Text = "DAC when Open";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(138, 54);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// pidCoefLabel
//
this.pidCoefLabel.AutoSize = true;
this.pidCoefLabel.Location = new System.Drawing.Point(28, 150);
this.pidCoefLabel.Name = "pidCoefLabel";
this.pidCoefLabel.Size = new System.Drawing.Size(78, 13);
this.pidCoefLabel.TabIndex = 11;
this.pidCoefLabel.Text = "PID Coefficient";
//
// pidCoefTextBox
//
this.pidCoefTextBox.Enabled = false;
this.pidCoefTextBox.Location = new System.Drawing.Point(138, 147);
this.pidCoefTextBox.Name = "pidCoefTextBox";
this.pidCoefTextBox.Size = new System.Drawing.Size(46, 20);
this.pidCoefTextBox.TabIndex = 12;
//
// storedPosReuseCheckBox
//
this.storedPosReuseCheckBox.AutoSize = true;
this.storedPosReuseCheckBox.Enabled = false;
this.storedPosReuseCheckBox.Location = new System.Drawing.Point(31, 174);
this.storedPosReuseCheckBox.Name = "storedPosReuseCheckBox";
this.storedPosReuseCheckBox.Size = new System.Drawing.Size(162, 17);
this.storedPosReuseCheckBox.TabIndex = 13;
this.storedPosReuseCheckBox.Text = "Enable stored position re-use";
this.storedPosReuseCheckBox.UseVisualStyleBackColor = true;
//
// RegulValveCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.storedPosReuseCheckBox);
this.Controls.Add(this.pidCoefTextBox);
this.Controls.Add(this.pidCoefLabel);
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.dacOpenTextBox);
this.Controls.Add(this.dacOpenLabel);
this.Controls.Add(this.dacClosedTextBox);
this.Controls.Add(this.dacClosedLabel);
this.Controls.Add(this.positionTextBox);
this.Controls.Add(this.positionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "RegulValveCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.RegulationValveCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox positionTextBox;
private System.Windows.Forms.Label positionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.Label dacClosedLabel;
private System.Windows.Forms.TextBox dacClosedTextBox;
private System.Windows.Forms.TextBox dacOpenTextBox;
private System.Windows.Forms.Label dacOpenLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
private System.Windows.Forms.Label pidCoefLabel;
private System.Windows.Forms.TextBox pidCoefTextBox;
private System.Windows.Forms.CheckBox storedPosReuseCheckBox;
}
}
@@ -0,0 +1,120 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegulValve
{
public partial class RegulValveCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(RegulValveCfgCtrl));
ComponentParametersDlg parent;
RegulValveCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as RegulValveCfg;
Redraw();
}
}
public RegulValveCfgCtrl()
{
InitializeComponent();
}
private void RegulationValveCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
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;
positionTextBox.Text = config.Position.ToString();
dacClosedTextBox.Text = config.DacValueClosed.ToString();
dacOpenTextBox.Text = config.DacValueOpen.ToString();
pidCoefTextBox.Text = config.PidCoef.ToString();
storedPosReuseCheckBox.Checked = config.StoredPositionReuse;
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
positionTextBox.Enabled = true;
dacClosedTextBox.Enabled = true;
dacOpenTextBox.Enabled = true;
pidCoefTextBox.Enabled = true;
storedPosReuseCheckBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 1 || dummy > 5)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Position' should be between 1 and 5";
}
if (!int.TryParse(dacClosedTextBox.Text, out dummy) || dummy < 0 || dummy > 1023)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'DAC when Closed' should be between 0 and 1023";
}
if (!int.TryParse(dacOpenTextBox.Text, out dummy) || dummy < 0 || dummy > 1023)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'DAC when Open' should be between 0 and 1023";
}
if (!int.TryParse(pidCoefTextBox.Text, out dummy) || dummy < 0 || dummy > 100)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'PID Coefficient' should be between 0 and 100";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.Position = int.Parse(positionTextBox.Text);
config.DacValueClosed = int.Parse(dacClosedTextBox.Text);
config.DacValueOpen = int.Parse(dacOpenTextBox.Text);
config.PidCoef = int.Parse(pidCoefTextBox.Text);
config.StoredPositionReuse = storedPosReuseCheckBox.Checked;
}
}
}
@@ -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>
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.RegulValve
{
public class RegulValveFactory : IComponentFactory
{
public string ClassName { get { return "RegulationValve"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 5; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new RegulValveCfg(this, "RegulationValve", "CB", 1, 100, 500, 20, false);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new RegulValveCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new RegulValve((RegulValveCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return RegulValveCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { RegulValve.ResetStaticProperties(); }
}
}
@@ -0,0 +1,269 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.GenericDevices;
namespace TBF.BenchControl.Elde.RegulValve
{
public class SetFlowOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp));
public override string ToString()
{
return string.Format("SetFlowOp({0},{1},{2})", regulValve.Name, reqFlowLo, reqFlowHi);
}
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly Elde.FlowMeter.FlowMeter flowMeter;
readonly Elde.RegulValve.RegulValve regulValve;
readonly int regulValveNr;
readonly int flowMeterNr;
readonly float reqFlowLo;
readonly float reqFlowHi;
readonly float reqFlowAve;
readonly int timeout;
readonly bool leaveMeasurementRunning;
/// Process values
enum OpState
{
Idle = 0,
ValveMoveToPosition,
SettingPosition,
ValveMoveToFlow,
SettingFlow,
FlowReached,
}
OpState opState;
float targetPositionLo;
float targetPositionHi;
int expireTime;
FloatBox measuredFlow;
/// <summary>
/// Set required water flow. Conditionally leave the measurement running.
/// Events: FlowSet, FlowTimeOut
/// </summary>
/// <param name="controlBoard">Control board device</param>
/// <param name="regulValve">Regulation valve component</param>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the flow to be achieved in [m3/h]</param>
/// <param name="requiredFlowHi">Upper limit of the flow to be achieved in [m3/h]</param>
/// <param name="timeout">Timeout for the flow setting in [s]</param>
/// <param name="leaveMeasurementRunning">true = Leave the measurement running after op. stop</param>
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
public SetFlowOp(ControlBoardDev controlBoard, IRegulValve regulValve, IFlowMeter flowMeter,
float requiredFlowLo, float requiredFlowHi, FloatBox measuredFlow, int timeout, bool leaveMeasurementRunning)
{
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
this.controlBoard = controlBoard;
this.regulValve = regulValve as Elde.RegulValve.RegulValve;
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
this.regulValveNr = this.regulValve.Position;
this.flowMeter = flowMeter as Elde.FlowMeter.FlowMeter;
if (flowMeter == null) throw new ArgumentNullException("flowMeter in null or not Elde");
this.flowMeterNr = this.flowMeter.Position;
this.reqFlowLo = requiredFlowLo;
this.reqFlowHi = requiredFlowHi;
this.reqFlowAve = (reqFlowLo + reqFlowHi) / 2.0f;
this.measuredFlow = measuredFlow;
this.timeout = timeout;
this.leaveMeasurementRunning = leaveMeasurementRunning;
log.Debug(this.ToString());
}
/// <summary>
/// Set required water flow - Do not leave the measurement running.
/// Events: FlowSet
/// </summary>
public SetFlowOp(ControlBoardDev controlBoard, IRegulValve regValve, IFlowMeter flowMeter,
float requiredFlowLo, float requiredFlowHi, FloatBox measuredFlow, int timeout)
: this(controlBoard, regValve, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout, false)
{
}
/// <summary>
/// Set required water flow - No timeout.
/// Events: FlowSet
/// </summary>
public SetFlowOp(ControlBoardDev controlBoard, IRegulValve regValve, IFlowMeter flowMeter,
float requiredFlowLo, float requiredFlowHi, FloatBox measuredFlow)
: this(controlBoard, regValve, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, int.MaxValue, false)
{
}
/// <summary>
/// Fetch target position limits from the dictionary or return false
/// </summary>
/// <param name="avgReqFlow">Average of the flow targer range (input)</param>
/// <param name="positionLo">Target valve position low limit (output)</param>
/// <param name="positionHi">Target valve position high limit (output)</param>
/// <returns>true when positions for the target flow are stored in the memory, otherwise return false</returns>
bool FetchTargetPosition(float avgReqFlow, out float positionLo, out float positionHi)
{
float targetPosition;
if (regulValve.Dict.TryGetValue(avgReqFlow, out targetPosition))
{
positionLo = Math.Max(targetPosition * 0.95f, 0.0f);
positionHi = Math.Min(targetPosition * 1.05f, 100.0f);
return true;
}
else
{
positionLo = 0.0f;
positionHi = 0.0f;
return false;
}
}
void StoreTargetPosition(float avgReqFlow, float actPosition)
{
if (!regulValve.Dict.ContainsKey(reqFlowAve))
{
regulValve.Dict.Add(new KeyValuePair<float, float>(avgReqFlow, actPosition));
}
return;
}
/// <summary>Start this operation</summary>
public void Start()
{
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
{
log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition;
}
else
{
log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi);
opState = OpState.ValveMoveToFlow;
}
expireTime = StateMachine.CurrentTime + timeout;
if (expireTime < 0) expireTime = int.MaxValue;
TestMethods tm = 0;
StopDevs sd = 0;
controlBoard.SendCommand(Command.Start, flowMeterNr, controlBoard.Route, int.MaxValue, tm,
0.0f, regulValve.RegulValveCfg.PidCoef, 0, sd);
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None, Event.FlowReached, Event.RegulValveTimeOut, Event.Error
/// </returns>
public Event Run()
{
float rvPosition = controlBoard.RValvePosition(regulValveNr);
float flowMtrFreq = controlBoard.ReferenceFreq;
float flow = flowMtrFreq * flowMeter.NominalFlow / 2000.0f;
if (measuredFlow != null) measuredFlow.F = flow;
log.InfoFormat("Run(): rv#={0} pos={1}% freq={2} flow={3} opState={4}",
regulValveNr, rvPosition.ToString("F1"), flowMtrFreq, flow, opState);
if (opState == OpState.ValveMoveToPosition)
{
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetPosition,
new float[2] { targetPositionLo, targetPositionHi });
opState = OpState.SettingPosition;
return Event.None;
}
else if (opState == OpState.SettingPosition)
{
if ((targetPositionLo <= rvPosition) && (rvPosition <= targetPositionHi))
{
opState = OpState.ValveMoveToFlow;
}
return Event.None;
}
else if (opState == OpState.ValveMoveToFlow)
{
if (reqFlowLo >= reqFlowHi || reqFlowLo > flowMeter.NominalFlow || reqFlowHi <= 0)
{
return Event.Error;
}
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi);
float freqLo = 2000.0f * reqFlowLo / flowMeter.NominalFlow;
float freqHi = 2000.0f * reqFlowHi / flowMeter.NominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi });
opState = OpState.SettingFlow;
return Event.None;
}
else if (opState == OpState.SettingFlow)
{
if ((reqFlowLo <= flow) && (flow <= reqFlowHi))
{
if (regulValve.RegulValveCfg.StoredPositionReuse)
{
float storedPosition;
if (regulValve.Dict.TryGetValue(reqFlowAve, out storedPosition))
{
/// update the stored valve position
StoreTargetPosition(reqFlowAve, (rvPosition + storedPosition) / 2.0f);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% stored={3} <--- Updating a stored position",
regulValveNr, reqFlowAve, rvPosition.ToString("F1"), storedPosition);
}
else
{
/// store the valve position
StoreTargetPosition(reqFlowAve, rvPosition);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% <--- Storing a new position",
regulValveNr, reqFlowAve, rvPosition.ToString("F1"));
}
}
opState = OpState.FlowReached;
return Event.FlowReached;
}
else if (StateMachine.CurrentTime > expireTime)
{
return Event.RegulValveTimeOut;
}
else
{
return Event.None;
}
}
else /// opState == OpState.FlowReached
{
return Event.FlowReached;
}
}
/// <summary>Start this operation</summary>
public void Stop()
{
opState = OpState.Idle;
if (leaveMeasurementRunning) return;
/// Stop measurement
TestMethods tm = 0;
StopDevs sd = StopDevs.RegValveRegulation;
controlBoard.SendCommand(Command.Stop, flowMeterNr, controlBoard.Route, 50000, tm,
0.0f, 20, 0, sd);
}
}
}
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.GenericDevices;
namespace TBF.BenchControl.Elde.RegulValve
{
public class SetRegulValvePositionOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SetRegulValvePositionOp));
public override string ToString()
{
return string.Format("SetRegulValvePositionOp({0},{1},{2})", regulValve.Name, posLoPct, posHiPct);
}
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly RegulValve regulValve;
readonly int regulValveNr;
readonly float posLoPct;
readonly float posHiPct;
readonly int timeout;
/// Process values
bool firstRun;
int expireTime;
bool positionReached;
/// <summary>
/// Set required water flow.
/// Events: FlowSet, FlowTimeOut
/// </summary>
/// <param name="controlBoard">Control board device</param>
/// <param name="regulValve">Regulation valve component</param>
/// <param name="posLoPct">Lower limit of the position to be achieved</param>
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
/// <param name="timeout">Timeout in sec. for setting the flow</param>
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
public SetRegulValvePositionOp(ControlBoardDev controlBoard, RegulValve regulValve, float posLoPct, float posHiPct, int timeout)
{
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
this.controlBoard = controlBoard;
this.regulValve = regulValve as RegulValve;
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
this.regulValveNr = this.regulValve.Position;
this.posLoPct = posLoPct;
this.posHiPct = posHiPct;
this.timeout = timeout;
log.Debug(this.ToString());
}
/// <summary>
/// Set required water flow - no timeout.
/// Events: FlowSet
/// </summary>
public SetRegulValvePositionOp(ControlBoardDev controlBoard, RegulValve regValve, float posLoPct, float posHiPct)
: this(controlBoard, regValve, posLoPct, posHiPct, int.MaxValue)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
firstRun = true;
positionReached = false;
expireTime = StateMachine.CurrentTime + timeout;
log.InfoFormat("Start(): RV#={0}, reqPosLo={1}%, reqPosHi={2}%", regulValveNr, posLoPct.ToString("F1"), posHiPct.ToString("F1"));
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.SetFlowDone
/// </returns>
public Event Run()
{
if (firstRun)
{
if (posLoPct >= posHiPct || posLoPct >= 100.0f || posHiPct <= 0)
{
return Event.Error;
}
firstRun = false;
controlBoard.ValveMove(regulValveNr,
RegulValveMode.TargetPosition,
new float[2] { posLoPct, posHiPct });
return Event.None;
}
if (positionReached) return Event.PositionReached;
float positionPct = controlBoard.RValvePosition(regulValveNr);
log.WarnFormat("Run(): RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
if (posLoPct >= posHiPct || posLoPct >= 100.0f || posHiPct <= 0)
{
return Event.Error;
}
else if (posLoPct <= positionPct && positionPct <= posHiPct)
{
positionReached = true;
return Event.PositionReached;
}
else if (StateMachine.CurrentTime > expireTime)
{
return Event.RegulValveTimeOut;
}
else
{
return Event.None;
}
}
/// <summary>Stop this operation</summary>
public void Stop()
{
controlBoard.ValveMove(regulValveNr,
RegulValveMode.Stop,
new float[2] { posLoPct, posHiPct });
}
}
}
@@ -0,0 +1,68 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class StartMeasurementOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(StartMeasurementOp));
public override string ToString() { return string.Format("StartMeasurementOp(ref={0},pulses={1})", flowMeter.Position, refPulses); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly Elde.FlowMeter.FlowMeter flowMeter;
readonly int refPulses; /// Number of reference pulses for a complete test
readonly TestMethods testMethod;
bool started = false;
/// <summary>
/// Starts the measurement.
/// Events: MeasurementStarted
/// </summary>
/// <param name="controlBoardDev">Control board component reference</param>
/// <param name="flowMeter">Flow meter component reference</param>
/// <param name="readers">Register readers references</param>
/// <param name="volume">Water volume for the test in liters</param>
public StartMeasurementOp(ControlBoardDev controlBoardDev, GenericDevices.IFlowMeter flowMeter, int refPulses, TestMethods method)
{
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
this.controlBoard = controlBoardDev;
this.flowMeter = flowMeter as Elde.FlowMeter.FlowMeter;
if (this.flowMeter == null) throw new ArgumentException("flowMeter is null or is not Elde");
this.refPulses = refPulses;
this.testMethod = method;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
controlBoard.SendCommand(Command.Start, flowMeter.Position, controlBoard.RRoute, refPulses, testMethod,
0.0f, 20, 0, StopDevs.None);
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (started) return Event.MeasurementStarted;
if (0 != (controlBoard.StatusP & StatusP.TestInProgress))
{
started = true;
return Event.MeasurementStarted;
}
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,63 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class StopPreviousOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(StopPreviousOp));
public override string ToString() { return string.Format("StopPreviousOp(.)"); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
bool stopped = false;
/// <summary>
/// Stop the previous control board operation (diverter, gate, etc.)
/// Events: None or PreviousStopped
/// </summary>
/// <param name="controlBoardDev">Control board component reference</param>
public StopPreviousOp(ControlBoardDev controlBoardDev)
{
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
this.controlBoard = controlBoardDev;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
controlBoard.SendCommand(Command.Stop,
0, /// ref. flowmeter number
controlBoard.RRoute, /// route
0, /// ref. pulses
TestMethods.Diverter,
0.0f,
20,
0,
StopDevs.Diverter | StopDevs.GatePulse | StopDevs.Reference | StopDevs.RegValveRegulation);
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None or Event.PreviousStopped
/// </returns>
public Event Run()
{
if (stopped) return Event.PreviousStopped;
if (0 == (controlBoard.StatusP & StatusP.TestCompleted))
{
stopped = true;
return Event.PreviousStopped;
}
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,57 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde.TempMeter
{
public class ReadTempOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadTempOp));
public override string ToString() { return string.Format("ReadTempOp(.,{0},{1},.)", eventDone, tempMeterNr); }
/// Set by the constructor
ControlBoardDev controlBoardDev;
Event eventDone;
int tempMeterNr;
FloatBox temp;
/// <summary>
/// Events: TempInDone, TempOutDone, TempDivDone or Error
/// </summary>
/// <param name="tempMeter">TempMeter reference</param>
/// <param name="temp">Reference to the variable, value is in degree Celsius</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadTempOp(TempMeter tempMeter, ref FloatBox temp, Event eventDone)
{
if (tempMeter == null) throw new ArgumentNullException("tempMeter");
this.controlBoardDev = tempMeter.ControlBoard;
this.tempMeterNr = tempMeter.Index;
this.temp = temp;
this.eventDone = eventDone;
log.Debug(this.ToString());
}
public ReadTempOp(TempMeter tempMeter, ref FloatBox temp)
: this(tempMeter, ref temp, Event.TempDone)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.TempInDone, Event.TempOutDone or Event.TempDivDone
/// </returns>
public Event Run()
{
temp.F = controlBoardDev.Temperature(tempMeterNr);
return eventDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.TempMeter
{
public class TempMeter : IComponent, GenericDevices.ITempMeter
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(TempMeter));
public override string ToString()
{
return string.Format("TempMeter({0},{1})", Name, Index);
}
public static void ResetStaticProperties() { }
TempMeterCfg tempMeterCfg;
public Generic.IComponentCfg Cfg { get { return tempMeterCfg; } }
public string Name { get { return tempMeterCfg.Name; } }
public readonly ControlBoardDev ControlBoard;
public readonly int Index; /// 0..7
public readonly float A1;
public readonly float A2;
public readonly float A3;
public readonly float A4;
public readonly float A5;
public TempMeter(TempMeterCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.tempMeterCfg = cfg;
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
Index = cfg.Position;
A1 = cfg.A1;
A2 = cfg.A2;
A3 = cfg.A3;
A4 = cfg.A4;
A5 = cfg.A5;
/// Prepare data for SendCalibData() control board component method
ControlBoard.TempCalibData[Index, 0] = A1;
ControlBoard.TempCalibData[Index, 1] = A2;
ControlBoard.TempCalibData[Index, 2] = A3;
ControlBoard.TempCalibData[Index, 3] = A4;
ControlBoard.TempCalibData[Index, 4] = A5;
log.Debug(this.ToString());
}
/// <summary>
/// Events: TempDone, Error
/// </summary>
/// <param name="temp">Reference to a variable for the temperature in Celsius</param>
/// <returns>ReadTempOp instance reference casted to IOperaton</returns>
public IOperation ReadTempOp(ref FloatBox temp)
{
return new ReadTempOp(this, ref temp);
}
/// <summary>
/// Events: tempDone, Error
/// </summary>
/// <param name="temp">Reference to a variable for the temperature in Celsius</param>
/// <param name="tempDone">Event returned when measurement done</param>
/// <returns>ReadTempOp instance reference casted to IOperaton</returns>
public IOperation ReadTempOp(ref FloatBox temp, Event tempDone)
{
return new ReadTempOp(this, ref temp, tempDone);
}
}
}
@@ -0,0 +1,78 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.TempMeter
{
public class TempMeterCfg : ComponentCfgBase, IChildComponentCfg
{
public int Position; /// 0..7
public float A1;
public float A2;
public float A3;
public float A4;
public float A5;
/// Parameterless constructor
public TempMeterCfg()
{
}
/// <summary>
/// Temperature meter configuration parameters
/// </summary>
/// <param name="name">Temperature meter name</param>
/// <param name="index">Position on the control board 0..7</param>
/// <param name="a1">A1</param>
/// <param name="a2">A2</param>
/// <param name="a3">A3</param>
/// <param name="a4">A4</param>
/// <param name="a5">A5</param>
public TempMeterCfg(IComponentFactory factory, string name, string parentName, int index, float a1, float a2, float a3, float a4, float a5)
: base(factory, name, parentName)
{
if (index < 0 || index > 7) throw new ArgumentOutOfRangeException("position");
this.Position = index;
this.A1 = a1;
this.A2 = a2;
this.A3 = a3;
this.A4 = a4;
this.A5 = a5;
}
public TempMeterCfg(IComponentFactory factory, string name, string parentName, int index)
: this(factory, name, parentName, index, -21.0116f, 0.0017727f, 0.00000000068422f, -7.40415E-16f, 0)
{
}
public IComponentCfg Clone()
{
return new TempMeterCfg(Factory, Name, ParentName, Position, A1, A2, A3, A4, A5);
}
public string ToString(int i)
{
return string.Format("index={0}, A1={1}, A2={2}, A3={3}, A4={4}, A5={5}", Position, A1, A2, A3, A4, A5);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
TempMeterCfg config = (TempMeterCfg)(new XmlSerializer(typeof(TempMeterCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,245 @@
namespace TBF.BenchControl.Elde.TempMeter
{
partial class TempMeterCfgCtrl
{
/// <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.positionTextBox = new System.Windows.Forms.TextBox();
this.positionLabel = new System.Windows.Forms.Label();
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.a1TextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.a2TextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.a3TextBox = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.a5TextBox = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.a4TextBox = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// positionTextBox
//
this.positionTextBox.Enabled = false;
this.positionTextBox.Location = new System.Drawing.Point(130, 82);
this.positionTextBox.Name = "positionTextBox";
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
this.positionTextBox.TabIndex = 6;
//
// positionLabel
//
this.positionLabel.AutoSize = true;
this.positionLabel.Location = new System.Drawing.Point(20, 85);
this.positionLabel.Name = "positionLabel";
this.positionLabel.Size = new System.Drawing.Size(44, 13);
this.positionLabel.TabIndex = 5;
this.positionLabel.Text = "Position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(20, 61);
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(130, 34);
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(20, 37);
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(127, 10);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// a1TextBox
//
this.a1TextBox.Enabled = false;
this.a1TextBox.Location = new System.Drawing.Point(130, 107);
this.a1TextBox.Name = "a1TextBox";
this.a1TextBox.Size = new System.Drawing.Size(130, 20);
this.a1TextBox.TabIndex = 8;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(20, 110);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(20, 13);
this.label1.TabIndex = 7;
this.label1.Text = "A1";
//
// a2TextBox
//
this.a2TextBox.Enabled = false;
this.a2TextBox.Location = new System.Drawing.Point(130, 128);
this.a2TextBox.Name = "a2TextBox";
this.a2TextBox.Size = new System.Drawing.Size(130, 20);
this.a2TextBox.TabIndex = 10;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(20, 131);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(20, 13);
this.label2.TabIndex = 9;
this.label2.Text = "A2";
//
// a3TextBox
//
this.a3TextBox.Enabled = false;
this.a3TextBox.Location = new System.Drawing.Point(130, 149);
this.a3TextBox.Name = "a3TextBox";
this.a3TextBox.Size = new System.Drawing.Size(130, 20);
this.a3TextBox.TabIndex = 12;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(20, 152);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(20, 13);
this.label3.TabIndex = 11;
this.label3.Text = "A3";
//
// a5TextBox
//
this.a5TextBox.Enabled = false;
this.a5TextBox.Location = new System.Drawing.Point(130, 191);
this.a5TextBox.Name = "a5TextBox";
this.a5TextBox.Size = new System.Drawing.Size(130, 20);
this.a5TextBox.TabIndex = 16;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(20, 194);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(20, 13);
this.label5.TabIndex = 15;
this.label5.Text = "A5";
//
// a4TextBox
//
this.a4TextBox.Enabled = false;
this.a4TextBox.Location = new System.Drawing.Point(130, 170);
this.a4TextBox.Name = "a4TextBox";
this.a4TextBox.Size = new System.Drawing.Size(130, 20);
this.a4TextBox.TabIndex = 14;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(20, 173);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(20, 13);
this.label4.TabIndex = 13;
this.label4.Text = "A4";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(130, 58);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// TempMeterCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.a5TextBox);
this.Controls.Add(this.label5);
this.Controls.Add(this.a4TextBox);
this.Controls.Add(this.label4);
this.Controls.Add(this.a3TextBox);
this.Controls.Add(this.label3);
this.Controls.Add(this.a2TextBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.a1TextBox);
this.Controls.Add(this.label1);
this.Controls.Add(this.positionTextBox);
this.Controls.Add(this.positionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "TempMeterCfgCtrl";
this.Size = new System.Drawing.Size(300, 240);
this.Load += new System.EventHandler(this.TempMeterCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox positionTextBox;
private System.Windows.Forms.Label positionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.TextBox a1TextBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox a2TextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox a3TextBox;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox a5TextBox;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox a4TextBox;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,140 @@
using System;
using System.Globalization;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.TempMeter
{
public partial class TempMeterCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(TempMeterCfgCtrl));
ComponentParametersDlg parent;
TempMeterCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as TempMeterCfg;
Redraw();
}
}
public TempMeterCfgCtrl()
{
InitializeComponent();
}
private void TempMeterCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
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;
positionTextBox.Text = config.Position.ToString();
a1TextBox.Text = config.A1.ToString();
a2TextBox.Text = config.A2.ToString();
a3TextBox.Text = config.A3.ToString();
a4TextBox.Text = config.A4.ToString();
a5TextBox.Text = config.A5.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
positionTextBox.Enabled = true;
a1TextBox.Enabled = true;
a2TextBox.Enabled = true;
a3TextBox.Enabled = true;
a4TextBox.Enabled = true;
a5TextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 0 || dummy > 7)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Position' should be between 0 and 7";
}
float fdummy;
if (!Utils.TryParseEFloat(a1TextBox.Text, out fdummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'A1' is not valid";
}
if (!Utils.TryParseEFloat(a2TextBox.Text, out fdummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'A2' is not valid";
}
if (!Utils.TryParseEFloat(a3TextBox.Text, out fdummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'A3' is not valid";
}
if (!Utils.TryParseEFloat(a4TextBox.Text, out fdummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'A4' is not valid";
}
if (!Utils.TryParseEFloat(a5TextBox.Text, out fdummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'A5' is not valid";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.Position = int.Parse(positionTextBox.Text);
bool updateOk = Utils.TryParseEFloat(a1TextBox.Text, out config.A1) &&
Utils.TryParseEFloat(a2TextBox.Text, out config.A2) &&
Utils.TryParseEFloat(a3TextBox.Text, out config.A3) &&
Utils.TryParseEFloat(a4TextBox.Text, out config.A4) &&
Utils.TryParseEFloat(a5TextBox.Text, out config.A5);
}
}
}
@@ -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>
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.TempMeter
{
public class TempMeterFactory : IComponentFactory
{
public string ClassName { get { return "TempMeter"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 8; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new TempMeterCfg(this, "TempMeter", "CB", 0);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new TempMeterCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new TempMeter((TempMeterCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return TempMeterCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { TempMeter.ResetStaticProperties(); }
}
}
@@ -0,0 +1,48 @@
using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class UpdateTankWeightOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(UpdateTankWeightOp));
public override string ToString() { return string.Format("UpdateTankWeightOp(.)"); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
/// <summary>
/// Stop the previous control board operation (diverter, gate, etc.)
/// Events: None or PreviousStopped
/// </summary>
/// <param name="controlBoardDev">Control board component reference</param>
public UpdateTankWeightOp(ControlBoardDev controlBoardDev)
{
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
this.controlBoard = controlBoardDev;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
controlBoard.UpdateWeights();
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.None or Event.PreviousStopped
/// </returns>
public Event Run()
{
controlBoard.UpdateWeights();
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.GenericDevices;
namespace TBF.BenchControl.Elde.Valve
{
public class SetValvesOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SetValvesOp));
/// Set by the constructor
ControlBoardDev controlBoard;
class SwitchPoint
{
public int TimeSec;
public IList<IValve> VOpen;
public IList<IValve> VClose;
public ulong MasksOpen;
public ulong MasksClose;
}
IList<SwitchPoint> switchPointsRaw;
IList<SwitchPoint> switchPoints;
int nextIx;
int swStartTime;
/// <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> CollectSwitchPoints(IList<IValve> valvesOpen, IList<IValve> valvesClose)
{
IList<SwitchPoint> result = new List<SwitchPoint>();
result.Add(new SwitchPoint { TimeSec = 0, VOpen = valvesOpen, VClose = valvesClose });
foreach (var valve in StateMachine.CoupledValves)
{
if ((!valve.Invert && valvesOpen.Contains(valve.CoupledTo)) ||
(valve.Invert && valvesClose.Contains(valve.CoupledTo)))
{
/// The coupled valve 'valve' is opening
int time = valve.LagOpening;
if (time == 0)
{
result[0].VOpen.Add(valve);
}
else
{
result.Add(new SwitchPoint { TimeSec = time,
VOpen = ValveBase.MakeList(valve),
VClose = new List<IValve>() });
}
}
else if ((!valve.Invert && valvesClose.Contains(valve.CoupledTo)) ||
(valve.Invert && valvesOpen.Contains(valve.CoupledTo)))
{
/// The coupled valve 'valve' is closing
int time = valve.LagClosing;
if (time == 0)
{
result[0].VClose.Add(valve);
}
else
{
result.Add(new SwitchPoint { TimeSec = time,
VOpen = new List<IValve>(),
VClose = ValveBase.MakeList(valve) });
}
}
}
return result;
}
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) point.MasksOpen |= (valve as Valve).Mask;
if (valve is Pump.Pump) point.MasksOpen |= (valve as Pump.Pump).Mask;
if (valve is PumpWithFM.Pump) point.MasksOpen |= (valve as PumpWithFM.Pump).Mask;
}
point.MasksClose = 0;
foreach (var valve in point.VClose)
{
if (valve is Valve) point.MasksClose |= (valve as Valve).Mask;
if (valve is Pump.Pump) point.MasksClose |= (valve as Pump.Pump).Mask;
if (valve is PumpWithFM.Pump) point.MasksClose |= (valve as PumpWithFM.Pump).Mask;
}
point.TimeSec += timeShift;
}
}
/// <summary>
/// Open and/or close multiple valves.
/// Events: ValvesSet
/// </summary>
/// <param name="controlBoard">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(ControlBoardDev controlBoard, IList<IValve> valvesOpen, IList<IValve> valvesClose)
{
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
this.controlBoard = controlBoard;
if (valvesOpen == null) valvesOpen = new List<IValve>();
if (valvesClose == null) valvesOpen = new List<IValve>();
switchPointsRaw = CollectSwitchPoints(valvesOpen, valvesClose);
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="controlBoard">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(ControlBoardDev controlBoard, IValve valveOpen, IValve valveClose)
: this(controlBoard, ValveBase.MakeList(valveOpen), ValveBase.MakeList(valveClose))
{
}
/// <summary>Start this operation</summary>
public void Start()
{
controlBoard.SetValves(switchPoints[0].MasksOpen, switchPoints[0].MasksClose);
swStartTime = StateMachine.CurrentTime;
nextIx = 1;
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.SetValvesDone
/// </returns>
public Event Run()
{
if (nextIx >= switchPoints.Count) return Event.ValvesSet;
if (StateMachine.CurrentTime >= swStartTime + switchPoints[nextIx].TimeSec)
{
controlBoard.SetValves(switchPoints[nextIx].MasksOpen, switchPoints[nextIx].MasksClose);
nextIx++;
}
return Event.None;
}
/// <summary>Start this operation</summary>
public void Stop()
{
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.GenericDevices;
namespace TBF.BenchControl.Elde.Valve
{
public class Valve : GenericDevices.ValveBase, Generic.IComponent, IValve
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(Valve));
public override string ToString()
{
return string.Format("Valve({0},{1},{2})", Name, bitPosition, (CoupledTo != null ? CoupledTo.Cfg.Name : "-"));
}
public static void ResetStaticProperties() { }
readonly ValveCfg valveCfg;
public Generic.IComponentCfg Cfg { get { return valveCfg; } }
readonly IValve coupledTo;
readonly ControlBoardDev controlBoard;
readonly int bitPosition; /// 0 .. 63
public string Name { get { return valveCfg.Name; } }
public IValve CoupledTo { get { return coupledTo; } }
public bool Invert { get { return valveCfg.Invert; } }
public int LagOpening { get { return valveCfg.LagOpening; } }
public int LagClosing { get { return valveCfg.LagClosing; } }
public readonly ulong Mask; /// derived from bitPosition in the constructor
public Valve(ValveCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.valveCfg = cfg;
controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
if (bitPosition < 0 || bitPosition >= 64) throw new ArgumentOutOfRangeException("position");
this.bitPosition = cfg.BitPosition;
this.Mask = (((ulong)1) << bitPosition);
if (cfg.CoupledToName != null)
{
this.coupledTo = (IValve)TbfComponents.FindComponent(cfg.CoupledToName, components);
}
log.Debug(this.ToString());
}
public bool State
{
get { return (controlBoard.Route & Mask) != 0; }
}
}
}
@@ -0,0 +1,67 @@
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Valve
{
public class ValveCfg : ComponentCfgBase, IChildComponentCfg
{
public int BitPosition; /// Bit-position
public string CoupledToName; /// Name of the coupled valve or null
public bool Invert; /// 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.
/// Parameterless constructor
public ValveCfg()
{
}
/// Constructor 1
public ValveCfg(IComponentFactory factory, string name, string parentName, int bitPosition, string coupledToName, bool invert, int lagOpening, int lagClosing)
: base(factory, name, parentName)
{
this.BitPosition = bitPosition;
this.CoupledToName = coupledToName;
this.Invert = invert;
this.LagOpening = lagOpening;
this.LagClosing = lagClosing;
}
/// Constructor 2 without CoupledTo valve
public ValveCfg(IComponentFactory factory, string name, string parentName, int bitPosition)
: this(factory, name, parentName, bitPosition, null, false, 0, 0)
{
}
public IComponentCfg Clone()
{
return new ValveCfg(Factory, Name, ParentName, BitPosition, CoupledToName, Invert, LagOpening, LagClosing);
}
public string ToString(int i)
{
return string.Format("bit={0}, coupledTo={1}, invert={2}, lagOpen={3}, lagClose={4}",
BitPosition, CoupledToName, (Invert ? "yes" : "no"), LagOpening, LagClosing);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr,
DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
ValveCfg config = (ValveCfg)(new XmlSerializer(typeof(ValveCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,214 @@
namespace TBF.BenchControl.Elde.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.invertCheckBox = 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.SuspendLayout();
//
// bitPositionTextBox
//
this.bitPositionTextBox.Enabled = false;
this.bitPositionTextBox.Location = new System.Drawing.Point(138, 82);
this.bitPositionTextBox.Name = "bitPositionTextBox";
this.bitPositionTextBox.Size = new System.Drawing.Size(81, 20);
this.bitPositionTextBox.TabIndex = 6;
//
// bitPositionLabel
//
this.bitPositionLabel.AutoSize = true;
this.bitPositionLabel.Location = new System.Drawing.Point(22, 85);
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(22, 60);
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(138, 33);
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(22, 36);
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(136, 13);
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(22, 124);
this.coupledToLabel.Name = "coupledToLabel";
this.coupledToLabel.Size = new System.Drawing.Size(56, 13);
this.coupledToLabel.TabIndex = 7;
this.coupledToLabel.Text = "Copled To";
//
// invertCheckBox
//
this.invertCheckBox.AutoSize = true;
this.invertCheckBox.Enabled = false;
this.invertCheckBox.Location = new System.Drawing.Point(232, 124);
this.invertCheckBox.Name = "invertCheckBox";
this.invertCheckBox.Size = new System.Drawing.Size(53, 17);
this.invertCheckBox.TabIndex = 9;
this.invertCheckBox.Text = "Invert";
this.invertCheckBox.UseVisualStyleBackColor = true;
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(138, 57);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// lagOpeningLabel
//
this.lagOpeningLabel.AutoSize = true;
this.lagOpeningLabel.Location = new System.Drawing.Point(22, 147);
this.lagOpeningLabel.Name = "lagOpeningLabel";
this.lagOpeningLabel.Size = new System.Drawing.Size(109, 13);
this.lagOpeningLabel.TabIndex = 10;
this.lagOpeningLabel.Text = "Lag when opening [s]";
//
// lagClosingLabel
//
this.lagClosingLabel.AutoSize = true;
this.lagClosingLabel.Location = new System.Drawing.Point(22, 171);
this.lagClosingLabel.Name = "lagClosingLabel";
this.lagClosingLabel.Size = new System.Drawing.Size(104, 13);
this.lagClosingLabel.TabIndex = 11;
this.lagClosingLabel.Text = "Lag when closing [s]";
//
// lagOpeningTextBox
//
this.lagOpeningTextBox.Enabled = false;
this.lagOpeningTextBox.Location = new System.Drawing.Point(138, 144);
this.lagOpeningTextBox.Name = "lagOpeningTextBox";
this.lagOpeningTextBox.Size = new System.Drawing.Size(81, 20);
this.lagOpeningTextBox.TabIndex = 12;
//
// lagClosingTextBox
//
this.lagClosingTextBox.Enabled = false;
this.lagClosingTextBox.Location = new System.Drawing.Point(138, 168);
this.lagClosingTextBox.Name = "lagClosingTextBox";
this.lagClosingTextBox.Size = new System.Drawing.Size(81, 20);
this.lagClosingTextBox.TabIndex = 13;
//
// coupledToComboBox
//
this.coupledToComboBox.Enabled = false;
this.coupledToComboBox.FormattingEnabled = true;
this.coupledToComboBox.Location = new System.Drawing.Point(138, 121);
this.coupledToComboBox.Name = "coupledToComboBox";
this.coupledToComboBox.Size = new System.Drawing.Size(81, 21);
this.coupledToComboBox.TabIndex = 14;
//
// ValveCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.coupledToComboBox);
this.Controls.Add(this.lagClosingTextBox);
this.Controls.Add(this.lagOpeningTextBox);
this.Controls.Add(this.lagClosingLabel);
this.Controls.Add(this.lagOpeningLabel);
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.invertCheckBox);
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(300, 200);
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.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 invertCheckBox;
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;
}
}
@@ -0,0 +1,125 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Valve
{
public partial class ValveCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(ValveCfgCtrl));
ComponentParametersDlg parent;
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;
if (parent.TbfComponents != null)
{
parentNameComboBox.Items.Add("---");
coupledToComboBox.Items.Add("---");
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.Valve.ValveFactory)
{
coupledToComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
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.BitPosition.ToString();
coupledToComboBox.Text = string.IsNullOrEmpty(config.CoupledToName) ? "---" : config.CoupledToName;
invertCheckBox.Checked = config.Invert;
lagOpeningTextBox.Text = config.LagOpening.ToString();
lagClosingTextBox.Text = config.LagClosing.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
bitPositionTextBox.Enabled = true;
coupledToComboBox.Enabled = true;
invertCheckBox.Enabled = true;
lagOpeningTextBox.Enabled = true;
lagClosingTextBox.Enabled = true;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.BitPosition = int.Parse(bitPositionTextBox.Text);
config.CoupledToName = coupledToComboBox.Text.Equals("---") ? string.Empty : coupledToComboBox.Text;
config.Invert = invertCheckBox.Checked;
config.LagOpening = int.Parse(lagOpeningTextBox.Text);
config.LagClosing = int.Parse(lagClosingTextBox.Text);
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!coupledToComboBox.Items.Contains(coupledToComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Coupled To'";
}
if (!int.TryParse(bitPositionTextBox.Text, out dummy) || dummy < 0 || dummy >= 64)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Bit Position' should be between 0 and 63";
}
if (!int.TryParse(lagOpeningTextBox.Text, out dummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Delay when opening' error";
}
if (!int.TryParse(lagClosingTextBox.Text, out dummy))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Delay when closing' error";
}
return flags;
}
}
}
@@ -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>
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.Valve
{
public class ValveFactory : IComponentFactory
{
public string ClassName { get { return "Valve"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return int.MaxValue; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new ValveCfg(this, "Valve", "CB", 0);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new ValveCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new Valve((ValveCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return ValveCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { Valve.ResetStaticProperties(); }
}
}