Initial commit almost identical to SVN-repo rev.340

This commit is contained in:
Milan Hanajik 2014-07-28 09:54:35 +02:00
commit 175a92f633
575 changed files with 186534 additions and 0 deletions

33
TestBenchFramework.sln Normal file
View File

@ -0,0 +1,33 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBF", "TestBenchFramework\TBF.csproj", "{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "TBFSetup", "TBFSetup\TBFSetup.vdproj", "{4890DE5C-9F68-40D7-B075-92C8EAB79833}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Debug|x86.ActiveCfg = Debug|x86
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Debug|x86.Build.0 = Debug|x86
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Release|Any CPU.Build.0 = Release|Any CPU
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Release|x86.ActiveCfg = Release|x86
{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}.Release|x86.Build.0 = Release|x86
{4890DE5C-9F68-40D7-B075-92C8EAB79833}.Debug|Any CPU.ActiveCfg = Debug
{4890DE5C-9F68-40D7-B075-92C8EAB79833}.Debug|x86.ActiveCfg = Debug
{4890DE5C-9F68-40D7-B075-92C8EAB79833}.Release|Any CPU.ActiveCfg = Release
{4890DE5C-9F68-40D7-B075-92C8EAB79833}.Release|Any CPU.Build.0 = Release
{4890DE5C-9F68-40D7-B075-92C8EAB79833}.Release|x86.ActiveCfg = Release
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

117
TestBenchFramework/AboutDlg.Designer.cs generated Normal file
View File

@ -0,0 +1,117 @@
namespace TestBenchFramework
{
partial class AboutDlg
{
/// <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 Windows Form 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.copyrightLabel = new System.Windows.Forms.Label();
this.versionLabel = new System.Windows.Forms.Label();
this.buildDateLabel = new System.Windows.Forms.Label();
this.closeButton = new System.Windows.Forms.Button();
this.logoPictureBox = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.SuspendLayout();
//
// copyrightLabel
//
this.copyrightLabel.AutoSize = true;
this.copyrightLabel.Location = new System.Drawing.Point(145, 19);
this.copyrightLabel.Name = "copyrightLabel";
this.copyrightLabel.Size = new System.Drawing.Size(90, 13);
this.copyrightLabel.TabIndex = 4;
this.copyrightLabel.Text = "Copyright © 2013";
//
// versionLabel
//
this.versionLabel.AutoSize = true;
this.versionLabel.Location = new System.Drawing.Point(145, 41);
this.versionLabel.Name = "versionLabel";
this.versionLabel.Size = new System.Drawing.Size(105, 13);
this.versionLabel.TabIndex = 5;
this.versionLabel.Text = "Version _VERSION_";
//
// buildDateLabel
//
this.buildDateLabel.AutoSize = true;
this.buildDateLabel.Location = new System.Drawing.Point(145, 64);
this.buildDateLabel.Name = "buildDateLabel";
this.buildDateLabel.Size = new System.Drawing.Size(136, 13);
this.buildDateLabel.TabIndex = 6;
this.buildDateLabel.Text = "Build date _BUILD_DATE_";
//
// closeButton
//
this.closeButton.DialogResult = System.Windows.Forms.DialogResult.OK;
this.closeButton.Location = new System.Drawing.Point(341, 36);
this.closeButton.Name = "closeButton";
this.closeButton.Size = new System.Drawing.Size(105, 28);
this.closeButton.TabIndex = 11;
this.closeButton.Text = "&Close";
this.closeButton.UseVisualStyleBackColor = true;
//
// logoPictureBox
//
this.logoPictureBox.BackgroundImage = global::TestBenchFramework.Properties.Resources.sensus_logo;
this.logoPictureBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.logoPictureBox.InitialImage = null;
this.logoPictureBox.Location = new System.Drawing.Point(12, 34);
this.logoPictureBox.Name = "logoPictureBox";
this.logoPictureBox.Size = new System.Drawing.Size(103, 30);
this.logoPictureBox.TabIndex = 12;
this.logoPictureBox.TabStop = false;
//
// AboutDlg
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Window;
this.ClientSize = new System.Drawing.Size(458, 99);
this.Controls.Add(this.logoPictureBox);
this.Controls.Add(this.closeButton);
this.Controls.Add(this.buildDateLabel);
this.Controls.Add(this.versionLabel);
this.Controls.Add(this.copyrightLabel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "AboutDlg";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "About Test Bench Framework";
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label copyrightLabel;
private System.Windows.Forms.Label versionLabel;
private System.Windows.Forms.Label buildDateLabel;
private System.Windows.Forms.Button closeButton;
private System.Windows.Forms.PictureBox logoPictureBox;
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace TestBenchFramework
{
/// <summary>
/// About dialog
/// </summary>
public partial class AboutDlg : Form
{
/// <summary>
/// Contsructor
/// </summary>
/// <param name="version">Language neutral version string</param>
/// <param name="buildDate">Regionally formated build date string</param>
public AboutDlg(string version, string buildDate)
{
InitializeComponent();
versionLabel.Text = versionLabel.Text.Replace("_VERSION_", version);
buildDateLabel.Text = buildDateLabel.Text.Replace("_BUILD_DATE_", buildDate);
}
}
}

View File

@ -0,0 +1,123 @@
<?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>
<metadata name="closeButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,173 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace TBF
{
/// <summary>
/// Data types and orientation of the table layout panel attached data.
/// </summary>
public enum Arrangement
{
RowOfIntegers,
RowOfDoubles,
RowOfStrings,
ColumnOfIntegers,
ColumnOfDoubles,
ColumnOfStrings,
}
/// <summary>
/// This class represents TextBox controls and data modified by them
/// that are attached to (=displayed inside) a TableLayoutPanel control.
/// </summary>
public class AttachedTextBoxes
{
///
/// Private fields
///
int count; /// Number of attached TextBoxes / cells
Arrangement arngmnt; /// Type of attachemnt (see above)
bool isRow; /// true if it is a row
TextBox[] textBoxes; /// TextBox controls to be aded to TableLayoutPanel
int[] intData; /// integer data |
double[] doubleData; /// double data |-> one of these three arrays is used
string[] stringData; /// string data |
/// <summary>
/// Constructor, which creates TextBox controls and adds them to the table layout panel.
/// </summary>
public AttachedTextBoxes(TableLayoutPanel tblLtPnl, Arrangement arngmnt, int firstColumn, int firstRow, int size)
{
this.count = size;
this.arngmnt = arngmnt;
isRow = (arngmnt == Arrangement.RowOfIntegers || arngmnt == Arrangement.RowOfDoubles || arngmnt == Arrangement.RowOfStrings);
textBoxes = new TextBox[count];
intData = new int[count];
doubleData = new double[count];
stringData = new string[count];
for (int i = 0; i < count; i++)
{
textBoxes[i] = new TextBox(); /// Crete a new TextBox control
if (isRow)
{
tblLtPnl.Controls.Add(textBoxes[i], firstColumn + i, firstRow);
}
else
{
tblLtPnl.Controls.Add(textBoxes[i], firstColumn, firstRow + i);
}
}
}
/// <summary>
/// Attached data array size
/// </summary>
public int Count { get { return count; } }
/// <summary>
/// Indexer returning a TextBox
/// </summary>
/// <param name="index">Index</param>
/// <returns>TextBox object reference</returns>
public TextBox this[int index]
{
get
{
if (index < 0 || index >= count)
{
return null;
}
else
{
return textBoxes[index];
}
}
}
/// <summary>
/// Retrieves data from the controls or detects a format error.
/// Wrong format in a cell interrupts data retrieving, so when the first control
/// contains data with wrong format, no data are retrieved at all.
/// </summary>
/// <returns>true if all data have correct format</returns>
public bool ValidateData()
{
switch (arngmnt)
{
case Arrangement.RowOfIntegers:
case Arrangement.ColumnOfIntegers:
for (int i = 0; i < count; i++)
{
if (!Int32.TryParse(textBoxes[i].Text, out intData[i])) return false;
}
return true;
case Arrangement.RowOfDoubles:
case Arrangement.ColumnOfDoubles:
for (int i = 0; i < count; i++)
{
if (!Double.TryParse(textBoxes[i].Text, out doubleData[i])) return false;
}
return true;
case Arrangement.RowOfStrings:
case Arrangement.ColumnOfStrings:
default:
return true;
}
}
/// <summary>
/// The following three methods provide initialization of controls with original data.
/// </summary>
public void SetData(int index, int value)
{
if (index < 0 || index >= count) return;
intData[index] = value;
textBoxes[index].Text = value.ToString();
}
public void SetData(int index, double value)
{
if (index < 0 || index >= count) return;
doubleData[index] = value;
textBoxes[index].Text = value.ToString();
}
public void SetData(int index, string value)
{
if (index < 0 || index >= count) return;
stringData[index] = value;
textBoxes[index].Text = value;
}
/// <summary>
/// The following three methods provide retrieving data from controls.
/// ValidateData() must be called first. The return value must be true.
/// </summary>
public int GetIntData(int index)
{
if (index < 0 || index >= count) return 0;
return intData[index];
}
public double GetDoubleData(int index)
{
if (index < 0 || index >= count) return 0;
return doubleData[index];
}
public string GetStringData(int index)
{
if (index < 0 || index >= count) return null;
return textBoxes[index].Text;
}
}
}

View File

@ -0,0 +1,72 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TBF
{
public class BarGraph
{
int originX; /// Left coordinate of the bar
int originY; /// Top coordinate of the bar
int barWidth; /// Bar width, the bar is actualy 1 pixel wider
int barHeight; /// Bar height the bat is actualy 1 pixel higher
Color barColor; /// Bar color
Color backColor; /// Background color (above the bar)
/// Bar border is always black, 1 pixel wide
int barValue; /// The actual bar size (the bar is drawn from bottom)
System.Windows.Forms.Control control;
Rectangle rect;
/// Use this setter to update the bar size
public float FValue
{
get { return (float)barValue/(float)barHeight; }
set
{
Value = (int)(value * (float)barHeight);
control.Invalidate();
}
}
/// Use this setter to update the bar size
public int Value
{
get { return barValue; }
set
{
if (value < 0) barValue = 0;
else if (value >= barHeight) barValue = barHeight;
else barValue = value;
control.Invalidate();
}
}
/// <summary>
/// Constructor
/// </summary>
public BarGraph(System.Windows.Forms.Control control, int originX, int originY, int barWidth, int barHeight, Color barColor, Color backColor)
{
this.control = control;
this.originX = originX;
this.originY = originY;
this.barWidth = barWidth;
this.barHeight = barHeight;
this.barColor = barColor;
this.backColor = backColor;
rect = new Rectangle(originX, originY, barWidth + 1, barHeight + 1);
barValue = 0;
}
/// <summary>
/// Call this function in Form1_Paint(..), pass the arguments without any modifications
/// </summary>
public void Paint(Graphics g)
{
g.FillRectangle(new SolidBrush(backColor), originX + 1, originY + 1, barWidth, barHeight - barValue);
g.FillRectangle(new SolidBrush(barColor), originX + 1, originY + barHeight + 1 - barValue, barWidth, barValue);
g.DrawRectangle(new Pen(Color.Black, 2.0F), originX, originY, barWidth + 1, barHeight + 1);
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using TBF.BenchControl;
namespace TBF.BenchControl.BenchId
{
/// <summary>
/// Holds information identifying the test bench.
/// </summary>
public class Component : ComponentBase, Generic.IComponent
{
readonly ComponentCfg benchIdCfg;
public static void ResetStaticProperties() { }
public int TestBenchNr { get { return benchIdCfg.TestBenchNr; } }
public Component(ComponentCfg cfg)
: base(cfg)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.benchIdCfg = cfg;
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.BenchId
{
/// <summary>
/// Holds information identifying the test bench - serializable configuration.
/// </summary>
public class ComponentCfg : ComponentCfgBase, Generic.IComponentCfg
{
public int TestBenchNr;
/// Parameterless constructor
public ComponentCfg()
{
}
public ComponentCfg(IComponentFactory factory, string name, int testBenchNr)
: base(factory, name)
{
TestBenchNr = testBenchNr;
}
public IComponentCfg Clone()
{
return new ComponentCfg(Factory, Name, TestBenchNr);
}
public string ToString(int i)
{
return string.Format("TestBenchNr = {0}", TestBenchNr);
}
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))
{
ComponentCfg config = (ComponentCfg)(new XmlSerializer(typeof(ComponentCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}

View File

@ -0,0 +1,63 @@
using System;
using System.Windows.Forms;
using TBF.BenchControl.Generic;
using TBF.Resources;
namespace TBF.BenchControl.BenchId
{
public partial class ComponentCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as ComponentCfg;
Redraw();
}
}
public ComponentCfgCtrl()
{
InitializeComponent();
}
private void EntryFormCfgCtrl_Load(object sender, EventArgs e)
{
nameLabel.Text = Strings.Name;
numberLabel.Text = Strings.Test_bench_number;
Redraw();
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
numberTextBox.Text = config.TestBenchNr.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
numberTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
try { config.TestBenchNr = int.Parse(numberTextBox.Text); }
catch { config.TestBenchNr = 1; }
}
}
}

View File

@ -0,0 +1,106 @@
namespace TBF.BenchControl.BenchId
{
partial class ComponentCfgCtrl
{
/// <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.numberLabel = new System.Windows.Forms.Label();
this.numberTextBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(135, 55);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
this.nameTextBox.TabIndex = 5;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(25, 58);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 4;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(132, 31);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(60, 13);
this.classNameLabel.TabIndex = 3;
this.classNameLabel.Text = "ClassName";
//
// numberLabel
//
this.numberLabel.AutoSize = true;
this.numberLabel.Location = new System.Drawing.Point(25, 86);
this.numberLabel.Name = "numberLabel";
this.numberLabel.Size = new System.Drawing.Size(44, 13);
this.numberLabel.TabIndex = 6;
this.numberLabel.Text = "Number";
//
// numberTextBox
//
this.numberTextBox.Enabled = false;
this.numberTextBox.Location = new System.Drawing.Point(135, 83);
this.numberTextBox.Name = "numberTextBox";
this.numberTextBox.Size = new System.Drawing.Size(57, 20);
this.numberTextBox.TabIndex = 7;
//
// ComponentCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.numberTextBox);
this.Controls.Add(this.numberLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "ComponentCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_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 numberLabel;
private System.Windows.Forms.TextBox numberTextBox;
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,40 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.BenchId
{
public class ComponentFactory : IComponentFactory
{
public string ClassName { get { return "Bench-ID"; } }
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 ComponentCfg(this, "Bench-ID", 1);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new ComponentCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new Component((ComponentCfg)config);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return ComponentCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { Component.ResetStaticProperties(); }
}
}

View File

@ -0,0 +1,48 @@
using System.Collections.Generic;
using TBF.BenchControl.GenericDevices;
namespace TBF.BenchControl
{
public class BenchPath
{
public int ItemNr;
public string Name;
public float Qfrom;
public float Qto;
public ITempMeter TempIn;
public ITempMeter TempOut;
public IPressureMeter PressIn;
public IPressureMeter PressOut;
public IList<IValve> ValvesOpen;
public IList<IValve> ValvesClose;
/// Constructor from name, the rest is empty
public BenchPath(string name, int itemNr)
{
ItemNr = itemNr;
Name = name;
ValvesOpen = new List<IValve>();
ValvesClose = new List<IValve>();
}
/// Constructor from data entity
public BenchPath(Entities.BenchPath entity, IList<BenchControl.Generic.IComponent> components)
: this(entity.Name, entity.ItemNr)
{
Qfrom = entity.Qfrom;
Qto = entity.Qto;
TempIn = (ITempMeter)TbfComponents.FindComponent(entity.TempIn, components);
TempOut = (ITempMeter)TbfComponents.FindComponent(entity.TempOut, components);
PressIn = (IPressureMeter)TbfComponents.FindComponent(entity.PressIn, components);
PressOut = (IPressureMeter)TbfComponents.FindComponent(entity.PressOut, components);
string[] vOpen = entity.ValvesOpen.Split(new char[] { ';' });
ValvesOpen = new List<IValve>();
foreach (var vName in vOpen) ValvesOpen.Add((IValve)TbfComponents.FindComponent(vName, components));
string[] vClose = entity.ValvesClose.Split(new char[] { ';' });
ValvesClose = new List<IValve>();
foreach (var vName in vClose) ValvesClose.Add((IValve)TbfComponents.FindComponent(vName, components));
}
}
}

View File

@ -0,0 +1,108 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;
using TBF.BenchControl;
using TBF.BenchControl.Generic;
using log4net;
namespace TBF.BenchControl.Cameras.CameraRoi
{
/// <summary>
/// IdcCamera object represents all IDC cameras.
/// Camera ID is an argument of most methods.
/// </summary>
public class CameraRoi : ComponentBase, IComponent, GenericDevices.ICameraRoi, GenericDevices.IRegisterReader
{
private static readonly ILog log = LogManager.GetLogger(typeof(CameraRoi));
public override string ToString() { return string.Format("{0}, roi{1}, parent={2}",
cameraRoiCfg.Name, cameraRoiCfg.RoiNr, Cfg.ParentName); }
public static void ResetStaticProperties()
{
}
readonly CameraRoiCfg cameraRoiCfg;
readonly GenericDevices.ICamera camera;
public GenericDevices.ICamera Camera { get { return camera; } }
public float PulsesPerLtr
{
get { return (ProcedureParams as RoiProcedureParams).GradPerLtr; }
}
public CameraRoi(CameraRoiCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.cameraRoiCfg = cfg;
if (cfg.DebugLevel != Entities.DebugMode.Off)
{
camera = TbfComponents.FindComponent(cfg.ParentName, components) as GenericDevices.ICamera;
if (camera == null) throw new Exception("Cannot find " + Name + " parent");
}
}
/// <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 flow meter pulses</param>
/// <returns>ReadWaterMeter instance reference casted to IOperaton</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>ReadWaterMeter instance reference casted to IOperaton</returns>
public IOperation ReadReferenceForRegisterOp(ref IntBox pulses, ref IntBox refPulses)
{
return null; /// not implemented
}
/// <summary>
/// Watermeter wheel/arrow detection process.
/// </summary>
/// <param name="roiId">Region of interest (1..4)</param>
/// <returns>Reference to operation object instance</returns>
public IOperation DetectOp()
{
RoiProcedureParams pp = ProcedureParams as RoiProcedureParams;
return camera.DetectOp(cameraRoiCfg.RoiNr,
new Cameras.IdcCamera.Command.Detect(cameraRoiCfg.RoiNr, 0, pp.IRoiX, pp.IRoiY, pp.IRoiW, pp.IRoiH,
pp.CX, pp.CY, pp.ORoiW, pp.ORoiH, pp.R1, pp.R2, pp.R3,
pp.Ang1, pp.Ang2, pp.AngStep, pp.CCW, (pp.CCW ? -30 : 30),
pp.SequenceLen, pp.SequenceTiming, pp.BackgroundCorr,
pp.BrightnessRoi * camera.Brightness));
}
/// <summary>
/// Watermeter wheel/arrow angle measurement process.
/// </summary>
/// <param name="roiId">Region of interest (1..4)</param>
/// <returns>Reference to operation object instance</returns>
public IOperation MeasureOp()
{
RoiProcedureParams pp = ProcedureParams as RoiProcedureParams;
return camera.MeasureOp(cameraRoiCfg.RoiNr,
new Cameras.IdcCamera.Command.Measure(cameraRoiCfg.RoiNr, true, 0, pp.IRoiX, pp.IRoiY, pp.IRoiW, pp.IRoiH,
pp.CX, pp.CY, pp.ORoiW, pp.ORoiH, pp.MinMvmt, pp.MaxMvmt,
pp.BrightnessRoi * camera.Brightness));
}
}
}

View File

@ -0,0 +1,54 @@
using System.IO;
using System.IO.Ports;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Cameras.CameraRoi
{
public class CameraRoiCfg : ComponentCfgBase, IChildComponentCfg
{
public int RoiNr; /// ROI number 1..4
/// Parameterless constructor
public CameraRoiCfg()
{
}
/// Constructor
public CameraRoiCfg(IComponentFactory factory, string name, string parentName, int roiNr)
: base(factory, name, parentName)
{
this.RoiNr = roiNr;
}
public IComponentCfg Clone()
{
return new CameraRoiCfg(Factory, Name, ParentName, RoiNr);
}
public string ToString(int i)
{
return string.Format("roi{0}, parent={1}", RoiNr, ParentName);
}
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))
{
CameraRoiCfg config = (CameraRoiCfg)(new XmlSerializer(typeof(CameraRoiCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}

View File

@ -0,0 +1,94 @@
using System;
using System.Windows.Forms;
using System.IO.Ports;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Cameras.CameraRoi
{
public partial class CameraRoiCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
CameraRoiCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as CameraRoiCfg;
Redraw();
}
}
public CameraRoiCfgCtrl()
{
InitializeComponent();
}
private void IdcCameraCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
parentNameComboBox.Items.Add("---");
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is BenchControl.Cameras.IdcCamera.IdcCameraFactory)
{
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;
roiTextBox.Text = config.RoiNr.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
roiTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
int dummy;
if (!int.TryParse(roiTextBox.Text, out dummy) || dummy < 1 || dummy > 4)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Region of Interest' 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.RoiNr = int.Parse(roiTextBox.Text);
}
}
}

View File

@ -0,0 +1,130 @@
namespace TBF.BenchControl.Cameras.CameraRoi
{
partial class CameraRoiCfgCtrl
{
/// <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.roiTextBox = new System.Windows.Forms.TextBox();
this.roiLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.parentNameLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(138, 72);
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, 75);
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, 46);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(89, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComponentName";
//
// roiTextBox
//
this.roiTextBox.Enabled = false;
this.roiTextBox.Location = new System.Drawing.Point(138, 121);
this.roiTextBox.Name = "roiTextBox";
this.roiTextBox.Size = new System.Drawing.Size(80, 20);
this.roiTextBox.TabIndex = 4;
//
// roiLabel
//
this.roiLabel.AutoSize = true;
this.roiLabel.Location = new System.Drawing.Point(28, 124);
this.roiLabel.Name = "roiLabel";
this.roiLabel.Size = new System.Drawing.Size(94, 13);
this.roiLabel.TabIndex = 3;
this.roiLabel.Text = "Region of Interest:";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(138, 96);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 6;
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(28, 99);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
this.parentNameLabel.TabIndex = 5;
this.parentNameLabel.Text = "Parent Name";
//
// CameraRoiCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Controls.Add(this.roiTextBox);
this.Controls.Add(this.roiLabel);
this.Name = "CameraRoiCfgCtrl";
this.Size = new System.Drawing.Size(300, 240);
this.Load += new System.EventHandler(this.IdcCameraCfgCtrl_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.TextBox roiTextBox;
private System.Windows.Forms.Label roiLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
private System.Windows.Forms.Label parentNameLabel;
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,46 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Cameras.CameraRoi
{
public class CameraRoiFactory : IComponentFactory
{
public string ClassName { get { return "CameraROI"; } }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 20; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new CameraRoiCfg(this, "ROI", "", 1);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new CameraRoiCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new CameraRoi((CameraRoiCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return CameraRoiCfg.CreateFromDbEntity(component, this);
}
public bool HasProcedureParams { get { return true; } }
//
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams)
{
return RoiProcedureParams.GetProcedureParams(procedureParams);
}
public bool HasTestParams { get { return false; } }
//
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public void ResetStaticProperties() { CameraRoi.ResetStaticProperties(); }
}
}

View File

@ -0,0 +1,74 @@
using System;
using log4net;
namespace TBF.BenchControl.Cameras.CameraRoi
{
public class ReadRegisterOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadRegisterOp));
public override string ToString() { return string.Format("ReadRegisterOp({0})", cameraRoi.Cfg.Name); }
/// Set by the constructor
readonly GenericDevices.ICameraRoi cameraRoi;
readonly BenchControl.Cameras.IdcCamera.IdcCamera camera;
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.ICameraRoi cameraRoi, ref IntBox pulses)
{
this.cameraRoi = cameraRoi;
if (cameraRoi == null) throw new ArgumentNullException("reader is null or it is not IdcCamera");
camera = cameraRoi.Camera as BenchControl.Cameras.IdcCamera.IdcCamera;
this.pulses = pulses;
log.Debug(this.ToString());
}
/// <summary>
/// Events: Event.ReadRegisterDone or Event.Error
/// </summary>
/// <param name="cameraRoi">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.ICameraRoi cameraRoi, ref IntBox pulses, ref IntBox refPulses)
: this(cameraRoi, ref pulses)
{
this.refPulses = refPulses;
log.Debug(this.ToString());
}
private void ReadPulses()
{
pulses.N = camera.Idc100.Pulses;
if (refPulses != null)
{
refPulses.N = 0;
}
}
/// <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()
{
}
}
}

View File

@ -0,0 +1,313 @@
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
using TBF.Resources;
namespace TBF.BenchControl.Cameras.CameraRoi
{
public class RoiProcedureParams : IParamsProvider, IProcedureParams
{
public int IRoiX;
public int IRoiY;
public int IRoiW;
public int IRoiH;
public float GradPerLtr;
public bool CCW; /// Clockwise = false, Counter clockwise = true
public float ORoiW;
public float ORoiH;
public float CX;
public float CY;
public float R1;
public float R2;
public float R3;
public float Ang1;
public float Ang2;
public float AngStep;
public int MinMvmt;
public int MaxMvmt;
public int SequenceLen;
public int SequenceTiming;
public int BackgroundCorr;
public float BrightnessRoi;
string[] paramNames = new string[]
{
"IRoiX",
"IRoiY",
"IRoiW",
"IRoiH",
"Grad per liter",
"CW/CCW",
"ORoiW",
"ORoiH",
"CX",
"CY",
"R1",
"R2",
"R3",
"Ang1",
"Ang2",
"AngStep",
"Min.Mvmt.",
"Max.Mvmt.",
"Det.Seq.Len",
"Det.Seq.Timing",
"Background",
"Brightness",
};
public string ParamName(int i) { return paramNames[i]; }
public string ToString(int i)
{
switch (i)
{
case 0: return IRoiX.ToString();
case 1: return IRoiY.ToString();
case 2: return IRoiW.ToString();
case 3: return IRoiH.ToString();
case 4: return GradPerLtr.ToString();
case 5: return (CCW ? "ccw" : "cw");
case 6: return ORoiW.ToString();
case 7: return ORoiH.ToString();
case 8: return CX.ToString();
case 9: return CY.ToString();
case 10: return R1.ToString();
case 11: return R2.ToString();
case 12: return R3.ToString();
case 13: return Ang1.ToString();
case 14: return Ang2.ToString();
case 15: return AngStep.ToString();
case 16: return MinMvmt.ToString();
case 17: return MaxMvmt.ToString();
case 18: return SequenceLen.ToString();
case 19: return SequenceTiming.ToString();
case 20: return BackgroundCorr.ToString();
case 21: return ((int)(100.0f * BrightnessRoi)).ToString();
default: return string.Empty;
}
}
/// <summary>
/// Parameterless constructor - sets default values of parameters.
/// </summary>
public RoiProcedureParams()
{
IRoiX = 60;
IRoiY = 1;
IRoiW = 520;
IRoiH = 478;
GradPerLtr = 40;
CCW = true;
ORoiW = 64.0f;
ORoiH = 64.0f;
CX = 31.0f;
CY = 31.0f;
R1 = 21.0f;
R2 = 31.0f;
R3 = 0;
Ang1 = 0;
Ang2 = 400.0f;
AngStep = 40.0f;
MinMvmt = 0;
MaxMvmt = 0;
SequenceLen = 8;
SequenceTiming = 1;
BackgroundCorr = 0;
BrightnessRoi = 1.0f;
}
public void UpdateParam(int i, string strValue)
{
switch (i)
{
case 0: IRoiX = int.Parse(strValue); return;
case 1: IRoiY = int.Parse(strValue); return;
case 2: IRoiW = int.Parse(strValue); return;
case 3: IRoiH = int.Parse(strValue); return;
case 4: GradPerLtr = Utils.ParseUFloat(strValue); return;
case 5: CCW = strValue.ToLower().Equals("ccw"); return;
case 6: ORoiW = Utils.ParseUFloat(strValue); return;
case 7: ORoiH = Utils.ParseUFloat(strValue); return;
case 8: CX = Utils.ParseUFloat(strValue); return;
case 9: CY = Utils.ParseUFloat(strValue); return;
case 10: R1 = Utils.ParseUFloat(strValue); return;
case 11: R2 = Utils.ParseUFloat(strValue); return;
case 12: R3 = Utils.ParseSFloat(strValue); return;
case 13: Ang1 = Utils.ParseSFloat(strValue); return;
case 14: Ang2 = Utils.ParseSFloat(strValue); return;
case 15: AngStep = Utils.ParseUFloat(strValue); return;
case 16: MinMvmt = int.Parse(strValue); return;
case 17: MaxMvmt = int.Parse(strValue); return;
case 18: SequenceLen = int.Parse(strValue); return;
case 19: SequenceTiming = int.Parse(strValue); return;
case 20: BackgroundCorr = int.Parse(strValue); return;
case 21: BrightnessRoi = ((float)int.Parse(strValue) / 100.0f); return;
default: return;
}
}
/// <summary>
/// Parses the text in the control to verify whether it represents a valid parameter.
/// </summary>
/// <param name="i">Parameter nr.</param>
/// <param name="strValue">String to be verified</param>
/// <param name="message">Message to be shown when verification fails</param>
/// <returns>'true' if parameter string is valid, 'false' otherwise</returns>
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
int iDummy;
float dummy;
switch (i)
{
case 0:
case 1:
case 2:
case 3:
case 16:
case 17:
case 18:
case 19:
case 20:
if (int.TryParse(strValue, out iDummy)) return true;
break;
case 4:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 15:
case 21:
if (Utils.TryParseUFloat(strValue, out dummy)) return true;
break;
case 12:
case 13:
case 14:
if (Utils.TryParseSFloat(strValue, out dummy)) return true;
break;
case 5:
if (strValue.ToLower().Equals("cw") || strValue.ToLower().Equals("ccw")) 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 RoiProcedureParams(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 RoiProcedureParams();
RoiProcedureParams procedureParams;
try
{
procedureParams = (RoiProcedureParams)(new XmlSerializer(typeof(RoiProcedureParams)))
.Deserialize(new StringReader(procedureParamsEntity.Parameters));
}
catch
{
procedureParams = new RoiProcedureParams();
}
procedureParams.procedureParamsEntity = procedureParamsEntity;
procedureParams.componentName = procedureParamsEntity.CmpntName;
procedureParams.procedure = procedureParamsEntity.Procedure;
return procedureParams;
}
#endregion
}
}

View File

@ -0,0 +1,15 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Connect : IWorkerCmd
{
public string CmdName { get { return "Connect"; } }
public int TimeoutMs;
public Connect(int timeoutMs)
{
this.TimeoutMs = timeoutMs;
}
}
}

View File

@ -0,0 +1,60 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Detect : IWorkerCmd
{
public string CmdName { get { return "Detect"; } }
public int RoiNr;
public int WMeterType;
public int IRoiX;
public int IRoiY;
public int IRoiW;
public int IRoiH;
public float CX;
public float CY;
public float ORoiW;
public float ORoiH;
public float R1;
public float R2;
public float R3;
public float Ang1;
public float Ang2;
public float AngStep;
public bool CCW; /// Clockwise = false, Counter clockwise = true
public float NomSpeed;
public int SequenceLen;
public int SequenceTiming;
public int BackgroundCorr;
public float Brightness; /// Overal brightness 0.0 .. 1.0 obtained as a product of the camera and the ROI brightness
public Detect(int roiNr, int wMeterType, int iRoiX, int iRoiY, int iRoiW, int iRoiH,
float cx, float cy, float oRoiW, float oRoiH,
float r1, float r2, float r3, float ang1, float ang2, float angStep, bool ccw,
float nomSpeed, int sequenceLen, int sequenceTiming, int backgroundCorr, float brightness)
{
this.RoiNr = roiNr;
this.WMeterType = wMeterType;
this.IRoiX = iRoiX;
this.IRoiY = iRoiY;
this.IRoiW = iRoiW;
this.IRoiH = iRoiH;
this.CX = cx;
this.CY = cy;
this.ORoiW = oRoiW;
this.ORoiH = oRoiH;
this.R1 = r1;
this.R2 = r2;
this.R3 = r3;
this.Ang1 = ang1;
this.Ang2 = ang2;
this.AngStep = angStep;
this.CCW = ccw;
this.NomSpeed = nomSpeed;
this.SequenceLen = sequenceLen;
this.SequenceTiming = sequenceTiming;
this.BackgroundCorr = backgroundCorr;
this.Brightness = brightness;
}
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Disconnect : IWorkerCmd
{
public string CmdName { get { return "Disconnect"; } }
public Disconnect()
{
}
}
}

View File

@ -0,0 +1,31 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Grab : IWorkerCmd
{
public string CmdName { get { return "Grab"; } }
public int X;
public int Y;
public int W;
public int H;
public int Scale;
public string FileName;
public FileFormat Format;
public float Brightness; /// Camera brightness 0.0 .. 1.0
bool WaitCompleted;
public Grab(string fileName, FileFormat format, float brihtness, bool waitCompleted)
{
X = 0;
Y = 0;
W = 640;
H = 480;
Scale = 1;
this.FileName = fileName;
this.Format = format;
this.Brightness = brihtness;
this.WaitCompleted = waitCompleted;
}
}
}

View File

@ -0,0 +1,44 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Measure : IWorkerCmd
{
public string CmdName { get { return "Measure"; } }
public int RoiNr; /// 1 or 2
public bool Triggered;
public int WMeterType;
public int IRoiX;
public int IRoiY;
public int IRoiW;
public int IRoiH;
public float CX;
public float CY;
public float ORoiW;
public float ORoiH;
public int MinMvmt;
public int MaxMvmt;
public float Brightness; /// Overal brightness 0.0 .. 1.0 obtained as a product of the camera and the ROI brightness
public Measure(int roiNr, bool triggered, int wMeterType,
int iRoiX, int iRoiY, int iRoiW, int iRoiH,
float cx, float cy, float oRoiW, float oRoiH,
int minMvmt, int maxMvmt, float brightness)
{
this.RoiNr = roiNr;
this.Triggered = triggered;
this.WMeterType = wMeterType;
this.IRoiX = iRoiX;
this.IRoiY = iRoiY;
this.IRoiW = iRoiW;
this.IRoiH = iRoiH;
this.CX = cx;
this.CY = cy;
this.ORoiW = oRoiW;
this.ORoiH = oRoiH;
this.MinMvmt = minMvmt;
this.MaxMvmt = maxMvmt;
this.Brightness = brightness;
}
}
}

View File

@ -0,0 +1,15 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Other : IWorkerCmd
{
public string CmdName { get { return "Other"; } }
public string Command;
public Other(string command)
{
this.Command = command;
}
}
}

View File

@ -0,0 +1,21 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
class Save : IWorkerCmd
{
public string CmdName { get { return "Save"; } }
public string VariableName;
public string FileName;
public FileFormat Format;
public bool WaitCompleted;
public Save(string variableName, string fileName, FileFormat format, bool waitCompleted)
{
this.VariableName = variableName;
this.FileName = fileName;
this.Format = format;
this.WaitCompleted = waitCompleted;
}
}
}

View File

@ -0,0 +1,15 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class SetBrightness : IWorkerCmd
{
public string CmdName { get { return "SetBrightness"; } }
public float Brightness; /// 0.0f .. 1.0f
public SetBrightness(float brightness)
{
this.Brightness = brightness;
}
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class StartNew : IWorkerCmd
{
public string CmdName { get { return "StartNew"; } }
public StartNew()
{
}
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class StopOp : IWorkerCmd
{
public string CmdName { get { return "StopOp"; } }
public StopOp()
{
}
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class StopStream : IWorkerCmd
{
public string CmdName { get { return "StopStream"; } }
public StopStream()
{
}
}
}

View File

@ -0,0 +1,19 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera.Command
{
public class Stream : IWorkerCmd
{
public string CmdName { get { return "Stream"; } }
public StreamType Type;
public FileFormat Format;
public float Brightness; /// Camera brightness 0.0 .. 1.0
public Stream(StreamType type, FileFormat format, float brightness)
{
this.Type = type;
this.Format = format;
this.Brightness = brightness;
}
}
}

View File

@ -0,0 +1,8 @@

namespace TBF.BenchControl.Cameras.IdcCamera
{
public interface IWorkerCmd
{
string CmdName { get; }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,297 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;
using TBF.BenchControl;
using TBF.BenchControl.Generic;
using log4net;
namespace TBF.BenchControl.Cameras.IdcCamera
{
/// <summary>
/// IdcCamera object represents all IDC cameras.
/// Camera ID is an argument of most methods.
/// </summary>
public class IdcCamera : ComponentBase, IDevice, IOperation, GenericDevices.ICamera
{
private static readonly ILog log = LogManager.GetLogger(typeof(IdcCamera));
public override string ToString() { return string.Format("{0}, com{1}, {2}, roi{3}",
idcCameraCfg.Name, idcCameraCfg.ComPortNr,
currentOp, currentRoiId); }
const int MaxRoisCount = 4;
/// <summary>
/// Enumeration of cameras via static fields and methods
/// </summary>
static int nextCameraNr = 0;
public static void ResetStaticProperties()
{
nextCameraNr = 0;
}
int cameraNr;
public int CameraNr { get { return cameraNr; } }
public float Brightness { get { return idcCameraCfg.BrightnessCam; } }
private readonly IdcCameraCfg idcCameraCfg;
/// <summary>
/// Currently running camera operation.
/// ReadRegisterOp-s are not included in this list, they are independent.
/// </summary>
public enum CurrentOp
{
None,
StartNew,
SetBrightness,
Grab,
Live,
Focus,
Detect,
Measure,
}
/// Private fields
public Idc100 Idc100; /// Idc100 camera low level implementation
CurrentOp currentOp;
int currentRoiId;
IWorkerCmd detectCmd;
IWorkerCmd measureCmd;
public IdcCamera(IdcCameraCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.idcCameraCfg = cfg;
cameraNr = nextCameraNr++;
}
public void Initialize()
{
if (idcCameraCfg.DebugLevel == Entities.DebugMode.Simulate)
{
log.WarnFormat("{0}: in simulation mode", Name);
return;
}
/// Initialize the camera
Idc100 = new Idc100(Name, cameraNr, idcCameraCfg.ComPortNr, idcCameraCfg.BaudRate, idcCameraCfg.BrightnessCam);
RetVal rVal = Idc100.StartOp(new Command.Connect(3000)); /// timeout in ms
if (idcCameraCfg.DebugLevel == Entities.DebugMode.AutoDetect)
{
if (rVal == RetVal.OK)
idcCameraCfg.DebugLevel = Entities.DebugMode.DetectedOn;
else
idcCameraCfg.DebugLevel = Entities.DebugMode.DetectedOff;
}
else if (rVal != RetVal.OK)
{
throw (new Exception(string.Format("Cannot make a connection to {0} on COM{1}", Name, idcCameraCfg.ComPortNr)));
}
if (idcCameraCfg.DebugLevel != Entities.DebugMode.DetectedOff)
{
log.WarnFormat("Detected: {0} on COM{1} ver. {2}", Name, idcCameraCfg.ComPortNr, Idc100.Version);
}
}
public void RunDeviceBefore()
{
}
public void RunDeviceAfter()
{
}
public void StopDevice()
{
if (Idc100 != null)
{
RetVal rVal = Idc100.StartOp(new Command.Disconnect());
Idc100.ShutDown();
}
}
/// <summary>
/// Restart the camera with a new firmware.
/// </summary>
/// <returns>Reference to operation object instance</returns>
public IOperation StartNewOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.StartNew;
return this;
}
/// <summary>
/// Set camera image brightness (camera aperture).
/// </summary>
/// <returns>Reference to operation object instance</returns>
public IOperation SetBrightnessOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.SetBrightness;
return this;
}
/// <summary>
/// Grab an image.
/// </summary>
/// <returns>Reference to operation object instance</returns>
public IOperation GrabOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.Grab;
return this;
}
/// <summary>
/// Display live image.
/// </summary>
/// <returns>Reference to operation object instance</returns>
public IOperation LiveOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.Live;
return this;
}
/// <summary>
/// Display live detail to focus the camera.
/// </summary>
/// <returns>Reference to operation object instance</returns>
public IOperation FocusOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.Focus;
return this;
}
/// <summary>
/// Watermeter wheel/arrow detection process.
/// </summary>
/// <param name="roiId">Region of interest (1..MaxRoisCount)</param>
/// <returns>Reference to operation object instance</returns>
public IOperation DetectOp(int roiId, IWorkerCmd detectCmd)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
if (roiId < 1 || roiId > MaxRoisCount) throw new ArgumentOutOfRangeException("roiId");
currentOp = CurrentOp.Detect;
this.currentRoiId = roiId;
this.detectCmd = detectCmd;
return this;
}
/// <summary>
/// Watermeter wheel/arrow angle measurement process.
/// </summary>
/// <param name="roiId">Region of interest (1..MaxRoisCount)</param>
/// <returns>Reference to operation object instance</returns>
public IOperation MeasureOp(int roiId, IWorkerCmd measureCmd)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
if (roiId < 1 || roiId > MaxRoisCount) throw new ArgumentOutOfRangeException("roiId");
currentOp = CurrentOp.Measure;
this.currentRoiId = roiId;
this.measureCmd = measureCmd;
return this;
}
/// <summary>Start the operation</summary>
public void Start()
{
if (Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn)
{
switch (currentOp)
{
case CurrentOp.StartNew:
Idc100.StartOp(new Command.StartNew());
return;
case CurrentOp.Grab:
Idc100.StartOp(new Command.Grab("snap1", FileFormat.Jpeg, Brightness, false));
return;
case CurrentOp.Live:
Idc100.StartOp(new Command.Stream(StreamType.SubSampled, FileFormat.Jpeg, Brightness));
return;
case CurrentOp.Focus:
Idc100.StartOp(new Command.Stream(StreamType.Focus, FileFormat.Bmp, Brightness));
return;
case CurrentOp.Detect:
Idc100.StartOp(this.detectCmd);
return;
case CurrentOp.Measure:
Idc100.StartOp(this.measureCmd);
return;
}
}
}
/// <summary>
/// Check the cameraDev state (OP_COMPLETED or OP_FAILED)
/// </summary>
/// <returns></returns>
public Event Run()
{
if (Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn)
{
switch (currentOp)
{
case CurrentOp.Grab:
if (Idc100.IdcState == IdcState.Idle) return Event.None;
else return Event.Error;
case CurrentOp.StartNew:
case CurrentOp.Live:
case CurrentOp.Focus:
case CurrentOp.Measure:
case CurrentOp.Detect:
if (Idc100.IdcState == IdcState.Busy)
{
return Event.CameraBusy;
}
else if (Idc100.IdcState == IdcState.OpCompleted)
{
log.InfoFormat("{0}: {1} - OpCompleted", cameraNr, currentOp);
return Event.CameraOpCompleted;
}
else if (Idc100.IdcState == IdcState.OpFailed)
{
log.WarnFormat("{0}: {1} - OpFailed", cameraNr, currentOp);
return Event.CameraOpFailed;
}
else return Event.Error;
default:
return Event.Error;
}
}
else
{
if (currentOp == CurrentOp.Grab)
{
return Event.None;
}
else
{
return Event.CameraOpCompleted;
}
}
}
/// <summary>Stop the operation</summary>
public void Stop()
{
if ((Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn)
&& (Idc100.IdcState != IdcState.Idle))
{
Idc100.StopOp();
}
currentOp = CurrentOp.None;
}
}
}

View File

@ -0,0 +1,57 @@
using System.IO;
using System.IO.Ports;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Cameras.IdcCamera
{
public class IdcCameraCfg : ComponentCfgBase, Generic.IComponentCfg
{
public int ComPortNr; /// Com port number 1..999
public int BaudRate; /// Baud rate 57600 or 115200
public float BrightnessCam; /// Relative brightness 0 .. 1.0f
/// Parameterless constructor
public IdcCameraCfg()
{
}
/// Constructor
public IdcCameraCfg(IComponentFactory factory, string name, int comPortNr, int baudRate, float brightnessCam)
: base(factory, name)
{
this.ComPortNr = comPortNr;
this.BaudRate = baudRate;
this.BrightnessCam = brightnessCam;
}
public IComponentCfg Clone()
{
return new IdcCameraCfg(Factory, Name, ComPortNr, BaudRate, BrightnessCam);
}
public string ToString(int i)
{
return string.Format("COM{0}, {1}Bd, brightness={2}%", ComPortNr, BaudRate, (int)(100.0f * BrightnessCam));
}
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))
{
IdcCameraCfg config = (IdcCameraCfg)(new XmlSerializer(typeof(IdcCameraCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}

View File

@ -0,0 +1,88 @@
using System;
using System.Windows.Forms;
using System.IO.Ports;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Cameras.IdcCamera
{
public partial class IdcCameraCfgCtrl : UserControl, IComponentCfgCtrl
{
IdcCameraCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as IdcCameraCfg;
Redraw();
}
}
public IdcCameraCfgCtrl()
{
InitializeComponent();
}
private void IdcCameraCfgCtrl_Load(object sender, EventArgs e)
{
baudRateComboBox.Items.Add("57600");
baudRateComboBox.Items.Add("115200");
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();
baudRateComboBox.Text = config.BaudRate.ToString();
brightnessTextBox.Text = (100.0f * config.BrightnessCam).ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
comPortNrTextBox.Enabled = true;
baudRateComboBox.Enabled = true;
brightnessTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
int dummy;
if (!int.TryParse(comPortNrTextBox.Text, out dummy) || dummy < 1 || dummy > 999)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Serial Port Number' is not valid";
}
if (!int.TryParse(baudRateComboBox.Text, out dummy) || ((dummy != 57600) && (dummy != 115200)))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Baud Rate' should be 57600 or 115200 Bd";
}
if (!int.TryParse(brightnessTextBox.Text, out dummy) || dummy < 0 || dummy > 100)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Brightness' 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.ComPortNr = int.Parse(comPortNrTextBox.Text);
config.BaudRate = int.Parse(baudRateComboBox.Text);
config.BrightnessCam = ((float)int.Parse(brightnessTextBox.Text) / 100.0f);
}
}
}

View File

@ -0,0 +1,176 @@
namespace TBF.BenchControl.Cameras.IdcCamera
{
partial class IdcCameraCfgCtrl
{
/// <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.baudRateLabel = new System.Windows.Forms.Label();
this.comPortNrTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.brightnessTextBox = new System.Windows.Forms.TextBox();
this.brightnessLabel = new System.Windows.Forms.Label();
this.baudRateComboBox = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(139, 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(29, 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(136, 21);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// baudRateLabel
//
this.baudRateLabel.AutoSize = true;
this.baudRateLabel.Location = new System.Drawing.Point(28, 102);
this.baudRateLabel.Name = "baudRateLabel";
this.baudRateLabel.Size = new System.Drawing.Size(58, 13);
this.baudRateLabel.TabIndex = 5;
this.baudRateLabel.Text = "Baud Rate";
//
// comPortNrTextBox
//
this.comPortNrTextBox.Enabled = false;
this.comPortNrTextBox.Location = new System.Drawing.Point(139, 73);
this.comPortNrTextBox.Name = "comPortNrTextBox";
this.comPortNrTextBox.Size = new System.Drawing.Size(80, 20);
this.comPortNrTextBox.TabIndex = 4;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(28, 76);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(98, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Serial Port Number:";
//
// brightnessTextBox
//
this.brightnessTextBox.Enabled = false;
this.brightnessTextBox.Location = new System.Drawing.Point(140, 126);
this.brightnessTextBox.Name = "brightnessTextBox";
this.brightnessTextBox.Size = new System.Drawing.Size(79, 20);
this.brightnessTextBox.TabIndex = 8;
//
// brightnessLabel
//
this.brightnessLabel.AutoSize = true;
this.brightnessLabel.Location = new System.Drawing.Point(28, 129);
this.brightnessLabel.Name = "brightnessLabel";
this.brightnessLabel.Size = new System.Drawing.Size(56, 13);
this.brightnessLabel.TabIndex = 7;
this.brightnessLabel.Text = "Brightness";
//
// baudRateComboBox
//
this.baudRateComboBox.FormattingEnabled = true;
this.baudRateComboBox.Location = new System.Drawing.Point(139, 99);
this.baudRateComboBox.Name = "baudRateComboBox";
this.baudRateComboBox.Size = new System.Drawing.Size(80, 21);
this.baudRateComboBox.TabIndex = 6;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(226, 129);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(15, 13);
this.label2.TabIndex = 9;
this.label2.Text = "%";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(226, 102);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(20, 13);
this.label3.TabIndex = 10;
this.label3.Text = "Bd";
//
// IdcCameraCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.baudRateComboBox);
this.Controls.Add(this.brightnessTextBox);
this.Controls.Add(this.brightnessLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Controls.Add(this.baudRateLabel);
this.Controls.Add(this.comPortNrTextBox);
this.Controls.Add(this.label1);
this.Name = "IdcCameraCfgCtrl";
this.Size = new System.Drawing.Size(300, 240);
this.Load += new System.EventHandler(this.IdcCameraCfgCtrl_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 baudRateLabel;
private System.Windows.Forms.TextBox comPortNrTextBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox brightnessTextBox;
private System.Windows.Forms.Label brightnessLabel;
private System.Windows.Forms.ComboBox baudRateComboBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,41 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Cameras.IdcCamera
{
public class IdcCameraFactory : IComponentFactory
{
public string ClassName { get { return "IdcCamera"; } }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 20; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new IdcCameraCfg(this, "Idc", 20, 57600, 0.5f);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new IdcCameraCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new IdcCamera((IdcCameraCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return IdcCameraCfg.CreateFromDbEntity(component, this);
}
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
//
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public void ResetStaticProperties() { IdcCamera.ResetStaticProperties(); }
}
}

View File

@ -0,0 +1,65 @@
using System;
namespace TBF.BenchControl.Cameras.IdcCamera
{
/// <summary>IDC camera states</summary>
public enum IdcState
{
Unchanged = -1, /// not a state - used in state transition tables
NotConnected = 0, /// 'gray'
Idle, /// 'green'
Busy, /// 'yellow' or 'orange'
OpCompleted, /// 'green'
OpFailed, /// 'red'
Halted, /// 'red'
}
public enum RetVal
{
OK = 0,
HOST_START = 1000, /// Start of error codes from HOST part of the software
Busy, /// OK - camera operation in progress
OpInterrupted, /// OK - camera operation interrupted
OpFailed, /// RetVal - Camera operation failed
CameraNotConnected, /// RetVal - Camera is not connected
SequenceError, /// RetVal - Invalid sequence of calls
InvalidComPortNr, /// RetVal - Invalid COM-port number
CannotOpenComPort, /// RetVal - Cannot open COM-port
CannotCommWithCamera, /// RetVal - Cannot communicate with the camera
CommTimeout, /// RetVal - Communication timeout
CommError, /// RetVal - Unknown error during communication
ShutdownInProgress, /// RetVal - System is shutting down
FatalError, /// RetVal - Fatal error
}
public struct IdcTransition
{
public RetVal RetVal;
public IdcState NewState;
public IdcTransition(RetVal retVal, IdcState newState)
{
this.RetVal = retVal;
this.NewState = newState;
}
}
public enum FileFormat
{
Bmp,
Jpeg,
}
public enum StreamType
{
Full,
SubSampled,
Focus,
}
enum WorkerCommand
{
StopOp, /// Stop the current operation
Timeout, /// The expected WorkerCommand(s) have not arrived in time
}
}

View File

@ -0,0 +1,227 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using log4net;
using TBF.UiBridge;
namespace TBF.BenchControl.Cameras.IdcCamera
{
///
/// File I/O implementation
///
public class SerialFileIO
{
static readonly ILog log = LogManager.GetLogger(typeof(SerialFileIO));
static TBF.Tools.ByteFormatter byteFormatter = new TBF.Tools.ByteFormatter();
const int BUFSIZE = 1024;
const int MAXFNAMESIZE = 62;
int cameraIdx;
string imagesPath;
StringBuilder fioFilenameBuilder;
string fioFullPathname;
int packetSize;
byte[] fioBuffer;
BinaryWriter fioWriter;
enum FioState
{
Command, /// 'o', 'c' or 'w'
Open, /// 'p'
Open2, /// 'e'
Open3, /// 'n'
Open4, /// 1
Filename,
Close, /// 'l'
Close2, /// 'o'
Close3, /// 's'
Close4, /// 'e'
Close5, /// 1
Write, /// 'r'
Write2, /// 'i'
Write3, /// 't'
Write4, /// 'e'
Write5, /// 1
PktSize1,
PktSize2,
PktSize3,
Data,
}
FioState state;
public string TransferredFile
{
get { return fioFullPathname; }
}
public SerialFileIO(int cameraIdx, string imagesPath)
{
this.cameraIdx = cameraIdx;
this.imagesPath = imagesPath;
state = FioState.Command;
fioFullPathname = string.Empty;
fioFilenameBuilder = new StringBuilder(16);
fioBuffer = new byte[BUFSIZE];
}
public void ProcessByte(byte b)
{
///
/// Reaching break in any case of the following switch is an error
///
if (state == FioState.Data)
{
if (packetSize > 0)
{
if (fioWriter != null)
{
fioWriter.Write(b);
}
if (--packetSize == 0)
{
state = FioState.Command;
}
return;
}
log.ErrorFormat("{0}: FIO error 17", cameraIdx);
}
else
{
switch (state)
{
case FioState.Command:
if ((char)b == 'o') { state = FioState.Open; return; }
if ((char)b == 'c') { state = FioState.Close; return; }
if ((char)b == 'w') { state = FioState.Write; return; }
log.ErrorFormat("{0}: FIO error 1, fullPathName={1}", cameraIdx, fioFullPathname);
break;
case FioState.Open:
if ((char)b == 'p') { state = FioState.Open2; return; }
log.ErrorFormat("{0}: FIO error 2", cameraIdx);
break;
case FioState.Open2:
if ((char)b == 'e') { state = FioState.Open3; return; }
log.ErrorFormat("{0}: FIO error 3", cameraIdx);
break;
case FioState.Open3:
if ((char)b == 'n') { state = FioState.Open4; return; }
log.ErrorFormat("{0}: FIO error 4", cameraIdx);
break;
case FioState.Open4:
if (b == 1)
{
fioFilenameBuilder.Clear();
state = FioState.Filename;
return;
}
log.ErrorFormat("{0}: FIO error 5", cameraIdx);
break;
case FioState.Filename:
if (b == 0)
{
if (fioWriter != null)
{
fioWriter.Close();
fioWriter.Dispose();
}
try
{
fioFullPathname = imagesPath + fioFilenameBuilder.ToString();
fioWriter = new BinaryWriter(File.Open(fioFullPathname, FileMode.Create));
log.DebugFormat("{0}: Open(\"{1}\")", cameraIdx, fioFullPathname);
}
catch
{
fioWriter = null;
log.WarnFormat("{0}: Failed to open(\"{1}\")", cameraIdx, fioFullPathname);
}
state = FioState.Command;
return;
}
else if (fioFilenameBuilder.Length < MAXFNAMESIZE)
{
fioFilenameBuilder.Append((char)b);
return;
}
log.ErrorFormat("{0}: FIO error 6", cameraIdx);
break;
case FioState.Close:
if ((char)b == 'l') { state = FioState.Close2; return; }
log.ErrorFormat("{0}: FIO error 7", cameraIdx);
break;
case FioState.Close2:
if ((char)b == 'o') { state = FioState.Close3; return; }
log.ErrorFormat("{0}: FIO error 8", cameraIdx);
break;
case FioState.Close3:
if ((char)b == 's') { state = FioState.Close4; return; }
log.ErrorFormat("{0}: FIO error 9", cameraIdx);
break;
case FioState.Close4:
if ((char)b == 'e') { state = FioState.Close5; return; }
log.ErrorFormat("{0}: FIO error 10", cameraIdx);
break;
case FioState.Close5:
if ((char)b == '1' && fioWriter != null)
{
log.DebugFormat("{0}: Close()", cameraIdx);
fioWriter.Close();
fioWriter.Dispose();
fioWriter = null;
Bridge.OnImageUpdated(this, new ImageUpdatedEventArgs(cameraIdx, fioFullPathname));
fioFullPathname = String.Empty;
state = FioState.Command;
return;
}
log.ErrorFormat("{0}: FIO error 11", cameraIdx);
break;
case FioState.Write:
if ((char)b == 'r') { state = FioState.Write2; return; }
log.ErrorFormat("{0}: FIO error 12", cameraIdx);
break;
case FioState.Write2:
if ((char)b == 'i') { state = FioState.Write3; return; }
log.ErrorFormat("{0}: FIO error 13", cameraIdx);
break;
case FioState.Write3:
if ((char)b == 't') { state = FioState.Write4; return; }
log.ErrorFormat("{0}: FIO error 14", cameraIdx);
break;
case FioState.Write4:
if ((char)b == 'e') { state = FioState.Write5; return; }
log.ErrorFormat("{0}: FIO error 15", cameraIdx);
break;
case FioState.Write5:
if ((char)b == '1') { state = FioState.PktSize1; return; }
log.ErrorFormat("{0}: FIO error 16", cameraIdx);
break;
case FioState.PktSize1:
packetSize = (int)b;
state = FioState.PktSize2;
return;
case FioState.PktSize2:
packetSize = (256 * packetSize) + (int)b;
state = FioState.PktSize3;
return;
case FioState.PktSize3:
packetSize = (256 * packetSize) + (int)b;
log.DebugFormat("{0}: write(len={1})", cameraIdx, packetSize);
state = FioState.Data;
return;
default:
log.ErrorFormat("{0}: FIO error 18", cameraIdx);
break;
}
}
state = FioState.Command;
}
}
}

View File

@ -0,0 +1,619 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Threading;
using log4net;
namespace TBF.BenchControl.Cameras.IdcCamera
{
public class SerialLayer
{
static readonly ILog log = LogManager.GetLogger(typeof(SerialLayer));
///
/// Set to true when shut-down is in progress
///
public static bool g_shutDown = false;
public bool m_disconnecting;
int cameraNr;
int comPortNr;
int baudRate;
int readTimeout;
string imagesPath;
Queue<byte> readQueue;
ManualResetEvent queueNotEmptyEvent;
SerialFileIO serialFileIO;
SerialPort serialPort;
byte[] singleCharWrBuff; /// predefined serial write buffer for 1 byte
byte[] twoCharsWrBuff; /// predefined serial write buffer for 2 bytes
#region Content switching, multiplexing
const byte CTRLZ = 26;
const byte CTRLQ = 17;
const byte XON = 17;
const byte CTRLS = 19;
const byte XOFF = 19;
/// <summary>
/// Multiplexed channel content ID (destination ID)
/// </summary>
enum Mux
{
Console, /// Command console, identified by CTRLZ + 'C' byte sequence
File, /// File download (ICD camera -> file), identified by CTRLZ = 'F' byte sequence
}
Mux lastWriteContentId;
Mux currentReadContentId;
bool lastReadCtrlZ;
#endregion
/// <summary>
/// Create a SerialLayer instance.
/// </summary>
/// <param name="cameraNr">0-based camera number</param>
/// <param name="comPortNr">COM port number 1..999</param>
/// <param name="baudRate">Baud rate 57600 or 115200</param>
/// <param name="readTimeout">Read timeout in ms</param>
/// <param name="imagesPath">Path to a folder where received files are stored</param>
public SerialLayer(int cameraNr, int comPortNr, int baudRate, int readTimeout, string imagesPath)
{
log.InfoFormat("new SerialLayer(ix={0}, com{1}, {2}Bd, tmout={3}ms, ipath={4})", cameraNr, comPortNr, baudRate, readTimeout, imagesPath);
this.cameraNr = cameraNr;
this.comPortNr = comPortNr;
this.baudRate = baudRate;
this.readTimeout = readTimeout;
this.imagesPath = imagesPath;
singleCharWrBuff = new byte[1];
twoCharsWrBuff = new byte[2];
twoCharsWrBuff[0] = CTRLZ;
m_disconnecting = false;
readQueue = new Queue<byte>();
queueNotEmptyEvent = new ManualResetEvent(false);
serialPort = new SerialPort();
serialPort.DataReceived += serialPort_DataReceived;
}
/// <summary>
/// Open the serial port.
/// </summary>
/// <returns>RetVal.OK or RetVal.CANNOT_OPEN_COMPORT</returns>
public RetVal OpenPort()
{
log.Info("OpenPort()");
if (serialPort.IsOpen) return RetVal.OK;
if (comPortNr<1 || comPortNr>999) return RetVal.CannotOpenComPort;
m_disconnecting = false;
/// Initialize FIFO, content switching, multiplexing
readQueue.Clear();
lastWriteContentId = Mux.Console;
currentReadContentId = Mux.Console;
lastReadCtrlZ = false;
serialFileIO = new SerialFileIO(cameraNr, imagesPath);
/// Finally open the serial port
try
{
serialPort.PortName = "COM" + comPortNr.ToString();
serialPort.BaudRate = baudRate;
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.Handshake = Handshake.None;
serialPort.RtsEnable = true;
serialPort.DtrEnable = true;
serialPort.ReadTimeout = 1000000; /// Sufficiently large, read timeout is applied to FIFO read
serialPort.WriteTimeout = SerialPort.InfiniteTimeout;
serialPort.Open();
}
catch (Exception e)
{
log.Error("Cannot open serial port COM" + comPortNr.ToString(), e);
return RetVal.CannotOpenComPort;
}
return RetVal.OK;
}
/// <summary>
/// Close the serial port.
/// </summary>
public void ClosePort()
{
log.InfoFormat("{0}: ClosePort()", cameraNr);
if (!serialPort.IsOpen) return;
m_disconnecting = true; /// Complete any pending I/O operations
serialPort.Close();
}
public void FifoFlush()
{
lock (readQueue) { readQueue.Clear(); }
}
public void UnlockLastRead()
{
lock (readQueue) { readQueue.Enqueue((byte)' '); } /// quit infinite fifo.Get() waiting
}
/// <summary>
/// Serial port data received event handler method
/// </summary>
/// <param name="sender">SerialPort</param>
/// <param name="e"></param>
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort.BytesToRead];
serialPort.Read(data, 0, data.Length);
foreach (byte dat in data)
{
byte b = dat;
if (lastReadCtrlZ)
{
lastReadCtrlZ = false;
if (dat == (byte)'C')
{
currentReadContentId = Mux.Console; /// Ctrl-Z + 'C' sequence detected: Mux.Console
continue;
}
if (dat == (byte)'F')
{
currentReadContentId = Mux.File; /// Ctrl-Z + 'F' sequence detected: Mux.File
continue;
}
if (dat == (byte)'1') b = (byte)XON; /// Ctrl-Z + '1' sequence detected: XON
if (dat == (byte)'2') b = (byte)XOFF; /// Ctrl-Z + '2' sequence detected: XOFF
}
else if (dat == CTRLZ)
{
lastReadCtrlZ = true;
continue;
}
///
/// Process demultiplexed data byte b appropriately
///
if (currentReadContentId == Mux.Console)
{
lock (readQueue)
{
readQueue.Enqueue(b);
queueNotEmptyEvent.Set();
}
}
else
{
serialFileIO.ProcessByte(b);
}
}
}
#region Read from readQueue
/// <summary>
/// Read one byte from the console content FIFO.
/// </summary>
/// <param name="response">Received byte</param>
/// <returns>RetVal.OK, RetVal.COMM_TIMEOUT or RetVal.SHUTDOWN</returns>
public RetVal ReadByte(out byte response)
{
if (g_shutDown || m_disconnecting)
{
response = 0;
log.DebugFormat("{0}: ReadByte() returns RetVal.SHUTDOWN", cameraNr);
return RetVal.ShutdownInProgress;
}
lock (readQueue)
{
if (readQueue.Count > 0)
{
response = readQueue.Dequeue();
return RetVal.OK;
}
else
{
queueNotEmptyEvent.Reset();
}
}
if (queueNotEmptyEvent.WaitOne(readTimeout))
{
lock (readQueue)
{
response = readQueue.Dequeue();
return RetVal.OK;
}
}
else
{
response = 0;
log.ErrorFormat("{0}: ReadByte() returns RetVal.COMM_TIMEOUT", cameraNr);
return RetVal.CommTimeout;
}
}
/// <summary>
/// Read bytes and form the output string until a delimiter character is received.
/// Output string excludes the delimiter.
/// </summary>
/// <param name="delimiter">Delimiter character</param>
/// <param name="text">Output string</param>
/// <returns>RetVal.OK, RetVal.COMM_TIMEOUT or RetVal.SHUTDOWN</returns>
RetVal ReadUntil(char delimiter, out string output)
{
StringBuilder buffer = new StringBuilder();
while (true)
{
RetVal retv;
byte znak;
if (RetVal.OK != (retv = ReadByte(out znak)))
{
output = buffer.ToString(); /// Copy data received so far to the output
log.Error("ReadUntil('" + delimiter.ToString() + "', out \"" + output + "\") returns " + retv.ToString());
return retv; /// Communication error
}
char c = (char)znak;
if (c == delimiter) break;
buffer.Append(c);
}
output = buffer.ToString();
return RetVal.OK;
}
/// <summary>
/// Read bytes and form the output string until "\r\n" is received.
/// Output string excludes "\r\n".
/// </summary>
/// <param name="text">Output string</param>
/// <returns>RetVal.OK, RetVal.COMM_TIMEOUT, RetVal.COMM_ERROR or RetVal.SHUTDOWN</returns>
RetVal ReadLine(out string output)
{
RetVal retv = ReadUntil('\r', out output);
if (retv != RetVal.OK) return retv;
/// Read the expected '\n'
byte znak;
if (RetVal.OK != (retv = ReadByte(out znak))) return retv;
if (znak != (byte)'\n')
{
log.Error("ReadLine(out \"" + output + "\") returns " + retv.ToString());
return RetVal.CommError;
}
return RetVal.OK;
}
#endregion
#region Write to serial port
/// <summary>
/// Write one byte (console content) to the serial port.
/// </summary>
/// <param name="b">Byte to send</param>
public void WriteByte(byte b)
{
WriteByte_Mux(b, Mux.Console);
}
/// <summary>
/// Write one byte from any source (either console or file) to the serial port.
/// Perform multiplexing - expansion to escape sequences using CTRLZ.
/// </summary>
/// <param name="b">Byte to send</param>
/// <param name="contentId">Mux.Console or Mux.File</param>
void WriteByte_Mux(byte b, Mux contentId)
{
if (contentId != lastWriteContentId)
{
/// Switching contentId when writing to a camera is not supported yet,
/// therefore this code within { } wont be invoked right now.
/// Send the content switch command CTRLZ + contentId
twoCharsWrBuff[1] = (contentId == Mux.Console) ? (byte)'C' : (byte)'F';
serialPort.Write(twoCharsWrBuff, 0, 2);
lastWriteContentId = contentId;
return;
}
if (b == CTRLZ)
{
/// If 'b'=CTRLZ send CTRLZ + CTRLZ
twoCharsWrBuff[1] = CTRLZ;
serialPort.Write(twoCharsWrBuff, 0, 2);
return;
}
else if (b == XON)
{
/// If 'b'=XON send CTRLZ + '1'
twoCharsWrBuff[1] = (byte)'1';
serialPort.Write(twoCharsWrBuff, 0, 2);
return;
}
else if (b == XOFF)
{
/// If 'b'=XON send CTRLZ + '2'
twoCharsWrBuff[1] = (byte)'2';
serialPort.Write(twoCharsWrBuff, 0, 2);
return;
}
else
{
/// Send a single regular byte 'b'
singleCharWrBuff[0] = b;
serialPort.Write(singleCharWrBuff, 0, 1);
return;
}
}
/// <summary>
/// Write a string (console content) to the serial port.
/// </summary>
/// <param name="str">String to send</param>
public void WriteString(string str)
{
if (str == null) return; /// There is nothing to send - return
if (str.EndsWith("\r\n"))
{
log.InfoFormat("{0}: WriteString(\"{1}\\r\\n\")", cameraNr, str.Substring(0, str.Length - 2));
}
else
{
log.InfoFormat("{0}: WriteString(\"{1}\")", cameraNr, str);
}
for (int i = 0; i < str.Length; i++) WriteByte((byte)str[i]);
}
#endregion
//-------------------------------------------------------------------------------
///////////////////////// Higher level console commands ///////////////////////
//-------------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Sends the specified command and waits for the following response.
// strings separated by spaces and terminated by <cr>
// Stores response into an array of CStrings pointed by pStrArray.
//
// Returns:
// positive numbers and 0
// The number of fields in the response. Returned number may be
// greater then arrayLen. Only the first arrayLen strings are saved.
// negative numbers
// negative error code returned by lower level functions:
// -RetVal.COMM_TIMEOUT = timeout occurred
// -RetVal.COMM_ERROR = all other errors
//---------------------------------------------------------------------------
public int CommandStr(string cmd, out string[] strArray, int nrFields, out string remaining)
{
StringBuilder tmp = new StringBuilder();
StringBuilder logStr = new StringBuilder();
StringBuilder rem = new StringBuilder();
lock (readQueue) { readQueue.Clear(); }
WriteString(cmd); /// send
strArray = null;
remaining = String.Empty;
string beforeGT;
RetVal retv = ReadUntil('>', out beforeGT);
if (retv != RetVal.OK) return -(int)retv; /// If Read... fails quit the loop ...
/// ... and return negative error code
/// Read the expected ' '
byte znak;
if (RetVal.OK != (retv = ReadByte(out znak))) return -(int)retv;
if (znak != (byte)' ') return -(int)RetVal.CommError;
/// Read fields after '>', parse the first field (the return code)
string received;
retv = ReadLine(out received);
if (retv != RetVal.OK) return -(int)retv;
strArray = received.Split(new char[] { ' ' }, nrFields + 1);
log.InfoFormat("{0}: Received: > {1}", cameraNr, received);
/// Skip until '$' received
retv = ReadUntil('$', out received);
if (retv != RetVal.OK) return -(int)retv;
/// Parse the return code (the 1st field)
int returnCode;
if (!int.TryParse(strArray[0], out returnCode) || returnCode < 0) return returnCode;
if (strArray.GetLength(0) == nrFields + 1) remaining = strArray[nrFields];
return Math.Min(strArray.GetLength(0), nrFields);
}
//---------------------------------------------------------------------------
// Sends the specified command and waits for the following response.
// integers separated by spaces and terminated by <cr>
// Stores response into an integer array pointed by pIntArray;
//
// Returns:
// positive numbers and 0
// The number of fields in the response. Returned number may be
// greater then arrayLen. Only the first arrayLen strings are saved.
// negative numbers
// negative error code returned by lower level functions
//---------------------------------------------------------------------------
public int CommandInt(string cmd, out int[] intArray, int nrFields, out string remaining)
{
string[] strArray;
int retv = CommandStr(cmd, out strArray, nrFields, out remaining);
if (retv <= 0)
{
intArray = null;
return retv;
}
intArray = new int[retv];
for (int i = 0; i < retv; i++)
{
int.TryParse(strArray[i], out intArray[i]);
}
return retv;
}
//---------------------------------------------------------------------------
// Sends the specified command and waits for the following response.
// real numbers separated by spaces and terminated by <cr>
// Stores response into a double array pointed by pDblArray;
//
// Returns:
// positive numbers and 0
// The number of fields in the response. Returned number may be
// greater then arrayLen. Only the first arrayLen strings are saved.
// negative numbers
// negative error code returned by lower level functions
//---------------------------------------------------------------------------
public int CommandDbl(string cmd, out double[] dblArray, int arrayLen, out string remaining)
{
string[] strArray;
int retv = CommandStr(cmd, out strArray, arrayLen, out remaining);
if (retv <= 0)
{
dblArray = null;
return retv;
}
dblArray = new double[retv];
for (int i = 0; i < retv; i++)
{
double.TryParse(strArray[i], out dblArray[i]);
}
return retv;
}
/// <summary>
/// Get camera version string
/// </summary>
/// <param name="versionStr">Version string</param>
/// <returns>RetVal.OK, RetVal.COMM_TIMEOUT, RetVal.COMM_ERROR, RetVal.SHUTDOWN or a camera ret.code (1..999)</returns>
public RetVal GetVer(out string versionStr)
{
log.DebugFormat("{0}: GetVer()", cameraNr);
versionStr = String.Empty;
StringBuilder tmp = new StringBuilder();
const int arrayLen = 1;
string[] strArray = new string[arrayLen];
lock (readQueue) { readQueue.Clear(); }
WriteString("info\r\n"); /// Send
/// Read info message until '>'
string infoMessage;
RetVal retv = ReadUntil('>', out infoMessage);
if (retv != RetVal.OK) return retv;
log.DebugFormat("{0}: InfoMessage: {1}", cameraNr, infoMessage);
/// Read the expected ' '
byte znak;
if (RetVal.OK != (retv = ReadByte(out znak))) return retv;
if (znak != (byte)' ') return RetVal.CommError;
/// Read fields after '>', parse the first field (the return code)
string tempStr;
retv = ReadLine(out tempStr);
if (retv != RetVal.OK) return retv;
string[] fields = tempStr.Split(new char[] { ' ' }, 2);
int returnCode;
if (!int.TryParse(fields[0], out returnCode) || returnCode < 0) return (RetVal)(-returnCode);
/// Skip until '$' received
retv = ReadUntil('$', out tempStr);
if (retv != RetVal.OK) return retv;
/// Parse the infoMessage
int pos1 = infoMessage.IndexOf("version = ");
if (pos1 != -1)
{
pos1 += "version = ".Length;
int pos2 = infoMessage.IndexOf("\r\n", pos1);
versionStr = infoMessage.Substring(pos1, pos2 - pos1);
log.InfoFormat("{0}: GetVer(out \"" + versionStr + "\")", cameraNr);
return RetVal.OK;
}
log.ErrorFormat("{0}: GetVer(...) returns RetVal.OP_FAILED", cameraNr);
return RetVal.CommError; /// Cannot read the version string
}
//----------------------------------------------------------------------------
// Check if livestream of serial characters is coming.
//
// Returns:
// RetVal.OK ..... not (OK),
// RetVal.BUSY ... yes (camera needs to be restarted)
//----------------------------------------------------------------------------
RetVal CheckLiveStream()
{
byte znak;
// 500 characters without timeout = stream
// copyright message is +/-350 characters long
for (int i=0; i<500; i++)
{
if (RetVal.CommTimeout == ReadByte(out znak)) return RetVal.OK; /// timeout ... no stream (OK)
}
#if true
// try to stop the stream
lock (readQueue) { readQueue.Clear(); }
WriteString("\r\nstopstream\r\n");
while (RetVal.CommTimeout != ReadByte(out znak)) { };
return RetVal.OK;
#else
// just report a running stream (RetVal.Busy)
return RetVal.Busy;
#endif
}
}
}

View File

@ -0,0 +1,46 @@
using TBF.BenchControl.Generic;
namespace TBF.BenchControl
{
public class ComponentBase : IComponent
{
Generic.IComponentCfg cfg;
public Generic.IComponentCfg Cfg { get { return cfg; } }
/// Constructor
public ComponentBase(Generic.IComponentCfg cfg)
{
this.cfg = cfg;
}
public string Name { get { return Cfg.Name; } }
/// <summary>
/// Reference to an object with procedure parameters
/// </summary>
public IParamsProvider ProcedureParams;
///
public void GetProcedureParams(TBF.Entities.Procedure procedure)
{
if (Cfg.Factory.HasProcedureParams)
{
ProcedureParams = TbfComponents.GetProcedureParams(this, procedure);
}
}
/// <summary>
/// Reference to an object with test parameters
/// </summary>
public IParamsProvider TestParams;
///
public void GetTestParams(TBF.Entities.Test test)
{
if (Cfg.Factory.HasTestParams)
{
TestParams = TbfComponents.GetTestParams(this, test);
}
}
}
}

View File

@ -0,0 +1,87 @@
using System.Collections.Generic;
using System.Xml.Serialization;
namespace TBF.BenchControl
{
public class ComponentCfgBase
{
[XmlIgnore]
public string Name
{
get { return name; }
set { name = value; }
}
string name;
[XmlIgnore]
public Generic.IComponentFactory Factory
{
get { return factory; }
set { factory = value; }
}
Generic.IComponentFactory factory;
[XmlIgnore]
public string ParentName
{
get { return parentName; }
set { parentName = value; }
}
string parentName;
[XmlIgnore]
public int ItemNr
{
get { return itemNr; }
set { itemNr = value; }
}
int itemNr;
[XmlIgnore]
public Entities.DebugMode DebugLevel
{
get { return debugLevel; }
set { debugLevel = value; }
}
Entities.DebugMode debugLevel;
[XmlIgnore]
public Entities.LogLevel LogLevel { get { return logLevel; } }
Entities.LogLevel logLevel;
[XmlIgnore]
public IList<Entities.MeasurementCorrection> Corrections { get { return corrections; } }
IList<Entities.MeasurementCorrection> corrections;
protected ComponentCfgBase()
{
itemNr = 0;
debugLevel = Entities.DebugMode.Normal;
logLevel = Entities.LogLevel.Off;
}
protected ComponentCfgBase(Generic.IComponentFactory factory, string name)
: this()
{
this.factory = factory;
this.name = name;
}
protected ComponentCfgBase(Generic.IComponentFactory factory, string name, string parentName)
: this(factory, name)
{
this.parentName = parentName;
}
protected void InitCfgBaseFromEntity(Entities.Component cmpntEntity, Generic.IComponentFactory factory)
{
name = cmpntEntity.Name;
parentName = cmpntEntity.ParentName;
itemNr = cmpntEntity.ItemNr;
debugLevel = cmpntEntity.Mode;
logLevel = cmpntEntity.Logging;
corrections = cmpntEntity.Corrections;
this.factory = factory;
}
}
}

View File

@ -0,0 +1,12 @@

namespace TBF.BenchControl
{
public static class Constants
{
/// <summary>
/// A fraction of the tank volume that is considered to be safe.
/// When the estimated test end tank volume exceeds this fraction, tank emptying is forced.
/// </summary>
public const float TankFullFactor = 0.9f;
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TBF.Entities;
namespace TBF.BenchControl
{
/// <summary>
/// This class keeps the current values used or measured by the test bench.
/// </summary>
public class Current
{
/// <summary>
/// Procedure, Tests and TestResults data
/// </summary>
public static Procedure Procedure;
public static Test Test;
public static int TestId = 0;
public static TestResult TestResult;
public static int TestResultId = 0;
/// <summary>
/// Measured data
/// </summary>
public static double StartMass;
public static double StopMass;
static Current()
{
}
/// Constructor
public Current()
{
/// There should always be some raw data
}
/// <summary>
/// Processes current 'tick' data during measurement.
/// </summary>
public static void ProcessTickData()
{
}
}
}

View File

@ -0,0 +1,193 @@
namespace TBF.BenchControl.DataEntry.Munich
{
partial class CycleBeginningForm
{
/// <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 Windows Form 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.okButton = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.mainStateTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.mainSnTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.auxStateTextBox = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.auxSnTextBox = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// okButton
//
this.okButton.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.okButton.ForeColor = System.Drawing.Color.Black;
this.okButton.Location = new System.Drawing.Point(439, 27);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(98, 63);
this.okButton.TabIndex = 0;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.mainStateTextBox);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.mainSnTextBox);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.groupBox1.ForeColor = System.Drawing.Color.Black;
this.groupBox1.Location = new System.Drawing.Point(28, 18);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(376, 92);
this.groupBox1.TabIndex = 1;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Hauptzähler";
//
// mainStateTextBox
//
this.mainStateTextBox.Location = new System.Drawing.Point(183, 56);
this.mainStateTextBox.Name = "mainStateTextBox";
this.mainStateTextBox.Size = new System.Drawing.Size(163, 31);
this.mainStateTextBox.TabIndex = 3;
this.mainStateTextBox.Visible = false;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(18, 59);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(74, 23);
this.label2.TabIndex = 2;
this.label2.Text = "Stand:";
this.label2.Visible = false;
//
// mainSnTextBox
//
this.mainSnTextBox.Location = new System.Drawing.Point(183, 37);
this.mainSnTextBox.Name = "mainSnTextBox";
this.mainSnTextBox.Size = new System.Drawing.Size(163, 31);
this.mainSnTextBox.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(18, 40);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(159, 23);
this.label1.TabIndex = 0;
this.label1.Text = "Seriennummer:";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.auxStateTextBox);
this.groupBox2.Controls.Add(this.label3);
this.groupBox2.Controls.Add(this.auxSnTextBox);
this.groupBox2.Controls.Add(this.label4);
this.groupBox2.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.groupBox2.ForeColor = System.Drawing.Color.Black;
this.groupBox2.Location = new System.Drawing.Point(28, 135);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(376, 92);
this.groupBox2.TabIndex = 2;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Nebenzähler";
//
// auxStateTextBox
//
this.auxStateTextBox.Location = new System.Drawing.Point(183, 54);
this.auxStateTextBox.Name = "auxStateTextBox";
this.auxStateTextBox.Size = new System.Drawing.Size(163, 31);
this.auxStateTextBox.TabIndex = 3;
this.auxStateTextBox.Visible = false;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(18, 57);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(74, 23);
this.label3.TabIndex = 2;
this.label3.Text = "Stand:";
this.label3.Visible = false;
//
// auxSnTextBox
//
this.auxSnTextBox.Location = new System.Drawing.Point(183, 37);
this.auxSnTextBox.Name = "auxSnTextBox";
this.auxSnTextBox.Size = new System.Drawing.Size(163, 31);
this.auxSnTextBox.TabIndex = 1;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(18, 40);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(159, 23);
this.label4.TabIndex = 0;
this.label4.Text = "Seriennummer:";
//
// CycleBeginningForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.BackColor = System.Drawing.Color.DarkGoldenrod;
this.ClientSize = new System.Drawing.Size(569, 255);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.okButton);
this.ForeColor = System.Drawing.Color.Black;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "CycleBeginningForm";
this.Text = "Daten";
this.TopMost = true;
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox mainStateTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox mainSnTextBox;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.TextBox auxStateTextBox;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox auxSnTextBox;
private System.Windows.Forms.Label label4;
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Windows.Forms;
namespace TBF.BenchControl.DataEntry.Munich
{
public partial class CycleBeginningForm : Form, GenericDevices.IHasCompleted
{
// To be retrieved after the form closes
public string MainSNText;
public string AuxSNText;
public string MainStateText;
public string AuxStateText;
// Set to 'true' when the form closes
public bool Completed { get { return completed; } }
bool completed;
public CycleBeginningForm()
{
InitializeComponent();
completed = false;
// TODO: localize strings
}
private void okButton_Click(object sender, EventArgs e)
{
MainSNText = mainSnTextBox.Text;
AuxSNText = auxSnTextBox.Text;
MainStateText = mainStateTextBox.Text;
AuxStateText = auxStateTextBox.Text;
completed = true;
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,264 @@
namespace TBF.BenchControl.DataEntry.Munich
{
partial class CycleEndForm
{
/// <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 Windows Form 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.groupBox2 = new System.Windows.Forms.GroupBox();
this.auxStateTextBox = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.mainStateTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.okButton = new System.Windows.Forms.Button();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.radioButton3 = new System.Windows.Forms.RadioButton();
this.radioButton2 = new System.Windows.Forms.RadioButton();
this.radioButton1 = new System.Windows.Forms.RadioButton();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.label4 = new System.Windows.Forms.Label();
this.qFallTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.qRiseTextBox = new System.Windows.Forms.TextBox();
this.groupBox2.SuspendLayout();
this.groupBox1.SuspendLayout();
this.groupBox3.SuspendLayout();
this.groupBox4.SuspendLayout();
this.SuspendLayout();
//
// groupBox2
//
this.groupBox2.Controls.Add(this.auxStateTextBox);
this.groupBox2.Controls.Add(this.label3);
this.groupBox2.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.groupBox2.ForeColor = System.Drawing.Color.Black;
this.groupBox2.Location = new System.Drawing.Point(25, 123);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(362, 81);
this.groupBox2.TabIndex = 4;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Nebenzähler";
//
// auxStateTextBox
//
this.auxStateTextBox.Location = new System.Drawing.Point(183, 31);
this.auxStateTextBox.Name = "auxStateTextBox";
this.auxStateTextBox.Size = new System.Drawing.Size(163, 31);
this.auxStateTextBox.TabIndex = 3;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(18, 34);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(74, 23);
this.label3.TabIndex = 2;
this.label3.Text = "Stand:";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.mainStateTextBox);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.groupBox1.ForeColor = System.Drawing.Color.Black;
this.groupBox1.Location = new System.Drawing.Point(25, 23);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(362, 81);
this.groupBox1.TabIndex = 3;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Hauptzähler";
//
// mainStateTextBox
//
this.mainStateTextBox.Location = new System.Drawing.Point(183, 31);
this.mainStateTextBox.Name = "mainStateTextBox";
this.mainStateTextBox.Size = new System.Drawing.Size(163, 31);
this.mainStateTextBox.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(18, 34);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(74, 23);
this.label2.TabIndex = 2;
this.label2.Text = "Stand:";
//
// okButton
//
this.okButton.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.okButton.ForeColor = System.Drawing.Color.Black;
this.okButton.Location = new System.Drawing.Point(425, 33);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(98, 63);
this.okButton.TabIndex = 5;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
//
// groupBox3
//
this.groupBox3.Controls.Add(this.radioButton3);
this.groupBox3.Controls.Add(this.radioButton2);
this.groupBox3.Controls.Add(this.radioButton1);
this.groupBox3.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.groupBox3.Location = new System.Drawing.Point(25, 223);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(362, 142);
this.groupBox3.TabIndex = 6;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Protokoll";
//
// radioButton3
//
this.radioButton3.AutoSize = true;
this.radioButton3.Location = new System.Drawing.Point(34, 100);
this.radioButton3.Name = "radioButton3";
this.radioButton3.Size = new System.Drawing.Size(152, 27);
this.radioButton3.TabIndex = 2;
this.radioButton3.TabStop = true;
this.radioButton3.Text = "radioButton3";
this.radioButton3.UseVisualStyleBackColor = true;
//
// radioButton2
//
this.radioButton2.AutoSize = true;
this.radioButton2.Location = new System.Drawing.Point(34, 67);
this.radioButton2.Name = "radioButton2";
this.radioButton2.Size = new System.Drawing.Size(152, 27);
this.radioButton2.TabIndex = 1;
this.radioButton2.TabStop = true;
this.radioButton2.Text = "radioButton2";
this.radioButton2.UseVisualStyleBackColor = true;
//
// radioButton1
//
this.radioButton1.AutoSize = true;
this.radioButton1.Location = new System.Drawing.Point(34, 34);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(152, 27);
this.radioButton1.TabIndex = 0;
this.radioButton1.TabStop = true;
this.radioButton1.Text = "radioButton1";
this.radioButton1.UseVisualStyleBackColor = true;
//
// groupBox4
//
this.groupBox4.Controls.Add(this.label4);
this.groupBox4.Controls.Add(this.qFallTextBox);
this.groupBox4.Controls.Add(this.label1);
this.groupBox4.Controls.Add(this.qRiseTextBox);
this.groupBox4.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.groupBox4.Location = new System.Drawing.Point(25, 383);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(361, 125);
this.groupBox4.TabIndex = 7;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Umschaltpunkte";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(18, 79);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(64, 23);
this.label4.TabIndex = 7;
this.label4.Text = "Qfall:";
//
// qFallTextBox
//
this.qFallTextBox.Location = new System.Drawing.Point(183, 77);
this.qFallTextBox.Name = "qFallTextBox";
this.qFallTextBox.Size = new System.Drawing.Size(163, 31);
this.qFallTextBox.TabIndex = 6;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(18, 37);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(80, 23);
this.label1.TabIndex = 5;
this.label1.Text = "Qsteig:";
//
// qRiseTextBox
//
this.qRiseTextBox.Location = new System.Drawing.Point(183, 34);
this.qRiseTextBox.Name = "qRiseTextBox";
this.qRiseTextBox.Size = new System.Drawing.Size(163, 31);
this.qRiseTextBox.TabIndex = 4;
//
// CycleEndForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DarkGoldenrod;
this.ClientSize = new System.Drawing.Size(559, 530);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.okButton);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "CycleEndForm";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Daten";
this.TopMost = true;
this.Load += new System.EventHandler(this.CycleEndForm_Load);
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.groupBox4.ResumeLayout(false);
this.groupBox4.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.TextBox auxStateTextBox;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox mainStateTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.RadioButton radioButton3;
private System.Windows.Forms.RadioButton radioButton2;
private System.Windows.Forms.RadioButton radioButton1;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox qFallTextBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox qRiseTextBox;
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Windows.Forms;
namespace TBF.BenchControl.DataEntry.Munich
{
public partial class CycleEndForm : Form, GenericDevices.IHasCompleted
{
// To be set before the form opens
public string ProtocolName1;
public string ProtocolName2;
public string ProtocolName3;
// To be retrieved after the form closes
public string MainStateText;
public string AuxStateText;
public string ProtocolTitle;
// Set to 'true' when the form closes
public bool Completed { get { return completed; } }
bool completed;
public CycleEndForm()
{
InitializeComponent();
completed = false;
// TODO: localize strings
}
private void CycleEndForm_Load(object sender, EventArgs e)
{
radioButton1.Text = ProtocolName1;
radioButton2.Text = ProtocolName2;
radioButton3.Text = ProtocolName3;
qRiseTextBox.Text = Sequences.SequenceBase.Qrise.ToString("F3");
qFallTextBox.Text = Sequences.SequenceBase.Qfall.ToString("F3");
}
private void okButton_Click(object sender, EventArgs e)
{
MainStateText = mainStateTextBox.Text;
AuxStateText = auxStateTextBox.Text;
float umsch;
if (Utils.TryParseUFloat(qRiseTextBox.Text, out umsch)) Sequences.SequenceBase.Qrise = umsch;
if (Utils.TryParseUFloat(qFallTextBox.Text, out umsch)) Sequences.SequenceBase.Qfall = umsch;
if (radioButton1.Checked) ProtocolTitle = ProtocolName1;
else if (radioButton2.Checked) ProtocolTitle = ProtocolName2;
else if (radioButton3.Checked) ProtocolTitle = ProtocolName3;
completed = true;
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using TBF.BenchControl;
namespace TBF.BenchControl.DataEntry.Munich
{
public class EntryForm : Generic.IComponent, IOperation, GenericDevices.IDataEntry, GenericDevices.IHasProtocolTitle
{
readonly EntryFormCfg entryFormCfg;
public Generic.IComponentCfg Cfg { get { return entryFormCfg; } }
public static void ResetStaticProperties() { }
public string Name { get { return entryFormCfg.Name; } }
/// <summary>
/// Properties set by the Begin and the End form
/// </summary>
public string MainBeginStateText { get { return mainBeginStateText; } }
string mainBeginStateText;
public string AuxBegintateText { get { return auxBeginStateText; } }
string auxBeginStateText;
public string ProtocolTitle { get { return protocolTitle; } }
string protocolTitle;
System.Windows.Forms.Form modelessDlg;
IList<GenericDevices.IWaterMeter> waterMeters;
public enum CurrentOp
{
None,
ShowFormAtCycleBeginning,
ShowFormAtCycleEnd,
}
CurrentOp currentOp;
public EntryForm(EntryFormCfg cfg)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.entryFormCfg = cfg;
currentOp = CurrentOp.None;
}
/// <returns>Reference to the operation</returns>
public IOperation ShowFormAtCycleBeginningOp(IList<GenericDevices.IWaterMeter> waterMeters)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.ShowFormAtCycleBeginning;
this.waterMeters = waterMeters;
return this;
}
/// <returns>Reference to the operation</returns>
public IOperation ShowFormAtCycleEndOp(IList<GenericDevices.IWaterMeter> waterMeters)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.ShowFormAtCycleEnd;
this.waterMeters = waterMeters;
return this;
}
delegate void EntryFormDlgt(EntryForm myRef);
///
void OpenBeginningDlg(EntryForm myRef)
{
myRef.modelessDlg = new CycleBeginningForm();
modelessDlg.Show();
}
///
void OpenEndDlg(EntryForm myRef)
{
CycleEndForm endForm = new CycleEndForm();
endForm.ProtocolName1 = entryFormCfg.ProtocolTitle1;
endForm.ProtocolName2 = entryFormCfg.ProtocolTitle2;
endForm.ProtocolName3 = entryFormCfg.ProtocolTitle3;
myRef.modelessDlg = endForm;
modelessDlg.Show();
}
/// <summary>Start this operation</summary>
public void Start()
{
switch (currentOp)
{
case CurrentOp.ShowFormAtCycleBeginning:
Program.MainWnd.Invoke(new EntryFormDlgt(OpenBeginningDlg), this);
break;
case CurrentOp.ShowFormAtCycleEnd:
Program.MainWnd.Invoke(new EntryFormDlgt(OpenEndDlg), this);
break;
}
}
/// <summary>Run this operation</summary>
/// <returns>Event.ResultsPrinted</returns>
public Event Run()
{
if (!(modelessDlg as GenericDevices.IHasCompleted).Completed) return Event.None;
if (modelessDlg is CycleBeginningForm)
{
if (waterMeters.Count >= 1 && waterMeters[0] != null)
{
mainBeginStateText = (modelessDlg as CycleBeginningForm).MainStateText;
waterMeters[0].SerialNr = (modelessDlg as CycleBeginningForm).MainSNText;
}
if (waterMeters.Count >= 2 && waterMeters[1] != null)
{
auxBeginStateText = (modelessDlg as CycleBeginningForm).AuxStateText;
waterMeters[1].SerialNr = (modelessDlg as CycleBeginningForm).AuxSNText;
}
}
else
{
if (waterMeters.Count >= 1 && waterMeters[0] != null)
{
waterMeters[0].State = (modelessDlg as CycleEndForm).MainStateText;
}
if (waterMeters.Count >= 2 && waterMeters[1] != null)
{
waterMeters[1].State = (modelessDlg as CycleEndForm).AuxStateText;
}
protocolTitle = (modelessDlg as CycleEndForm).ProtocolTitle;
}
return Event.Done;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
modelessDlg = null;
currentOp = CurrentOp.None;
}
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.DataEntry.Munich
{
public class EntryFormCfg : ComponentCfgBase, Generic.IComponentCfg
{
public string ProtocolTitle1;
public string ProtocolTitle2;
public string ProtocolTitle3;
/// Parameterless constructor
public EntryFormCfg()
{
}
/// <summary>
/// Data entry form configuration parameters
/// </summary>
/// <param name="factory">Data entry form factory</param>
/// <param name="name">Component name</param>
public EntryFormCfg(IComponentFactory factory, string name,
string protocolTitle1, string protocolTitle2, string protocolTitle3)
: base(factory, name)
{
this.ProtocolTitle1 = protocolTitle1;
this.ProtocolTitle2 = protocolTitle2;
this.ProtocolTitle3 = protocolTitle3;
}
public IComponentCfg Clone()
{
return new EntryFormCfg(Factory, Name, ProtocolTitle1, ProtocolTitle2, ProtocolTitle3);
}
public string ToString(int i)
{
return string.Empty;
}
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))
{
EntryFormCfg config = (EntryFormCfg)(new XmlSerializer(typeof(EntryFormCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.DataEntry.Munich
{
public partial class EntryFormCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(EntryFormCfgCtrl));
EntryFormCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as EntryFormCfg;
Redraw();
}
}
public EntryFormCfgCtrl()
{
InitializeComponent();
}
private void EntryFormCfgCtrl_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;
protocolTitle1TextBox.Text = config.ProtocolTitle1;
protocolTitle2TextBox.Text = config.ProtocolTitle2;
protocolTitle3TextBox.Text = config.ProtocolTitle3;
}
public void Unlock()
{
nameTextBox.Enabled = true;
protocolTitle1TextBox.Enabled = true;
protocolTitle2TextBox.Enabled = true;
protocolTitle3TextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ProtocolTitle1 = protocolTitle1TextBox.Text;
config.ProtocolTitle2 = protocolTitle2TextBox.Text;
config.ProtocolTitle3 = protocolTitle3TextBox.Text;
}
}
}

View File

@ -0,0 +1,152 @@
namespace TBF.BenchControl.DataEntry.Munich
{
partial class EntryFormCfgCtrl
{
/// <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.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.protocolTitle1TextBox = new System.Windows.Forms.TextBox();
this.protocolTitle2TextBox = new System.Windows.Forms.TextBox();
this.protocolTitle3TextBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(137, 57);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
this.nameTextBox.TabIndex = 5;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(27, 60);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 4;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(134, 33);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 3;
this.classNameLabel.Text = "ComonentName";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(27, 86);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(74, 13);
this.label1.TabIndex = 6;
this.label1.Text = "Protocol title 1";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(27, 112);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(74, 13);
this.label2.TabIndex = 7;
this.label2.Text = "Protocol title 2";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(27, 138);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(74, 13);
this.label3.TabIndex = 8;
this.label3.Text = "Protocol title 3";
//
// protocolTitle1TextBox
//
this.protocolTitle1TextBox.Enabled = false;
this.protocolTitle1TextBox.Location = new System.Drawing.Point(137, 83);
this.protocolTitle1TextBox.Name = "protocolTitle1TextBox";
this.protocolTitle1TextBox.Size = new System.Drawing.Size(130, 20);
this.protocolTitle1TextBox.TabIndex = 9;
//
// protocolTitle2TextBox
//
this.protocolTitle2TextBox.Enabled = false;
this.protocolTitle2TextBox.Location = new System.Drawing.Point(137, 109);
this.protocolTitle2TextBox.Name = "protocolTitle2TextBox";
this.protocolTitle2TextBox.Size = new System.Drawing.Size(130, 20);
this.protocolTitle2TextBox.TabIndex = 10;
//
// protocolTitle3TextBox
//
this.protocolTitle3TextBox.Enabled = false;
this.protocolTitle3TextBox.Location = new System.Drawing.Point(137, 135);
this.protocolTitle3TextBox.Name = "protocolTitle3TextBox";
this.protocolTitle3TextBox.Size = new System.Drawing.Size(130, 20);
this.protocolTitle3TextBox.TabIndex = 11;
//
// EntryFormCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.protocolTitle3TextBox);
this.Controls.Add(this.protocolTitle2TextBox);
this.Controls.Add(this.protocolTitle1TextBox);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "EntryFormCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_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 label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox protocolTitle1TextBox;
private System.Windows.Forms.TextBox protocolTitle2TextBox;
private System.Windows.Forms.TextBox protocolTitle3TextBox;
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,40 @@
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.DataEntry.Munich
{
public class EntryFormFactory : IComponentFactory
{
public string ClassName { get { return "DataEntryForm-Munich"; } }
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 EntryFormCfg(this, "DataEntryForm-Munich", "Protokoll Werkprüfung", "Protokoll 2", "Protokoll 3");
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new EntryFormCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new EntryForm((EntryFormCfg)config);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return EntryFormCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { EntryForm.ResetStaticProperties(); }
}
}

View File

@ -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,
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -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);
}
}
}

View File

@ -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(); }
}
}

View File

@ -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()
{
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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; }
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -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(); }
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -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(); }
}
}

View File

@ -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()
{
}
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -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(); }
}
}

View File

@ -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()
{
}
}
}

View File

@ -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; }
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -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(); }
}
}

View File

@ -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
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show More